Double Buffering in F#: what is the deal with the flicker? - winforms

I am trying to implement double buffering in F#. All of the examples I am running into are C#.
let r = form.DisplayRectangle
let buffer = new Bitmap(r.Width,r.Height)
form.DrawToBitmap(buffer,r)
form.BackgroundImage <-buffer
form.Invalidate()
Although the problem is an "easy" fix, the private variables are not exposed in F#. Instead, I have to initialize the form in C#. There must be a way though (it seems like this is a trivial thing) to expose the private variables for the form in F#.

Do
form.DoubleBuffered <- true
then no flicker

Related

OxyPlot performance issue on larg data in WPF on InvalidatePlot

I'm using OxyPlot in my wpf application as line recorder. It's like the LiveDemo example.
On a larg visible data set, I get some UI performance issues and may the whole application could freez. It seems to be PlotModel.InvalidatePlot which is called with to many points to often, but I didn't found a better way.
In deep:
Using OxyPlot 2.0.0
I code all in the PlotModel. The Xaml PlotView is only binding to the PlotModel.
I cyclical collect data in a thread an put them in a DataSource (List of List which are ItemSoure for the LineSeries)
I have a class which calculates cyclical in a thread the presentation for x and y axis and a bit more. After all this stuff, it calls PlotModel.InvalidatePlot.
If I
have more than 100 k points on the display (no matter if in multiple LineSeries or not)
and add 1 DataPoint per LineSeries every 500 ms
and call PlotModel.InvalidatePlot every 200 ms
not only the PlotView has performance issues, also the window is very slow in reaction, even if I call PlotModel.InvalidatePlot (false).
My goal
My goal would be that the Windo / Application is working normally. It should not hang up because of a line recorder. The best would be if it has no performance issues, but I'm skeptical.
What I have found or tested
OxyPlot has Performance guidelines. I'm using ItemsSource with DataPoints. I have also tried adding them directly to the LineSeris.Points, but then the Plot doesn’t refresh anyway (even with an ObservableCollection), so I have to call PlotModel.InvalidatePlot, what results in the same effect. I cannot bind to a defined LineSeries in Xaml because I don’t know how much Lines will be there. Maybe I missed something on adding the points directly?
I have also found a Github issue 1286 which is describing a related problem, but this workaround is slower in my tests.
I have also checked the time which is elapsed on the call of PlotModel.InvalidatePlot, but the count of points does not affect it.
I have checked the UI thread and it seems it have trouble to handle this large set of points
If I zoom in to the plot and display under 20 k Points it looks so
Question:
Is there a way to handle this better, except to call PlotModel.InvalidatePlot much less?
Restrictions:
I also must Update Axis and Annotations. So, I think I will not come around to call PlotModel.InvalidatePlot.
I have found that using the OxyPlot Windows Forms implementation and then displaying it using Windows Form integration in WPF gives much better performance.
e.g.
var plotView = new OxyPlot.WindowsForms.PlotView();
plotView.Model = Plot;
var host = new System.Windows.Forms.Integration.WindowsFormsHost();
host.Child = plotView;
PlotContainer = host;
Where 'Plot' is the PlotModel you call InvalidatePlot() on.
And then in your XAML:
<ContentControl Content="{Binding PlotContainer}"/>
Or however else you want to use your WindowsFormsHost.
I have a similar problem and found that you can use a Decimator in LineSeries. It is documented in the examples: LineSeriesExamples.cs
The usage is like this:
public static PlotModel WithXDecimator()
{
var model = new PlotModel { Title = "LineSeries with X Decimator" };
var s1 = CreateSeriesSuitableForDecimation();
s1.Decimator = Decimator.Decimate;
model.Series.Add(s1);
return model;
}
This may solve the problem on my side, and I hope it helps others too. Unfortunately it is not documented in the documentation
For the moment I ended up with calculating the time for calling InvalidatePlot for the next time. I calculate it with the method given in this answer, wich returns the number of visible points. This rededuce the performance issue, but dosent fix the block on the UI Thread on calling InvalidatePlot.

Using "using" statements for every object implementing IDisposable?

I'm currently skimming through some code that reads Active Directory entries and manipulates them. Since I haven't had to do with this kind of stuff, I F12'd the classes (DirectoryEntry, SearchResultCollection, ...), and I found out they all implement the IDisposable interface, but I couldn't see any using blocks in our code.
Are those even necessary in this case (i.e., should I blindly refactor them in)?
Another question of mine regarding this (there are very many instantiated IDisposable objects in the code: Isn't IDisposable making stuff very "ugly" in this case? I mean, I like using statements as they basically free my mind from worrying about things, but in many cases the code has a layout similar to the following:
using (var one = myObject.GetSomeDisposableObject())
using (var two = myObject.GetSomeOtherDisposableObject())
{
one.DoSomething();
using (var foo = new DisposableFoo())
{
MyMethod(foo);
using (...)
using (...)
{
...
}
}
}
I feel that this becomes quite unreadable due to high indentation levels (even stacking the using statements). But extracting some of this into new methods can lead to many parameters that need to be passed, since naturally the "inner" code often needs the objects created in the using statements.
What is an elegant way to solve this without losing readability?
For the first part, this question refers to 'memory used by the task increasing constantly' when not disposing of AD references
For the second, a using block is syntactic sugar for a try/finally with the Dispose call in the finally block, which would be an alternative construct allowing you to dispose of everything in one place, reducing indentation

Immutable State - Propagating Changes to the GUI Efficiently

In a previous question I asked how to idiomatically implement an observer pattern for an F# application. My application now uses a MailboxProcessor as reccomended and I've created some helper functions to create sub-MailboxProcessor's etc. However, I'm at a mental block when it comes to specific case scenarios w.r.t. GUI binding.
Lets say I have a model as such:
type Document = {
Contents : seq<DocumentObject>
}
And the GUI (WPF, XAML) requires binding like so:
interface IMainWindowViewModel
{
IEnumerable<Control> ContentViews { get; }
}
Each ViewModel for each Control will require a DocumentObject (its underlying model) and a way of knowing if it has changed. I supply this as a sub-MailboxProcessor<DocumentObject> so that changes may be propagated correctly, I'm moderately confident this pattern works. Essentially, it maps the service outputs and wraps modification requests (outer interface example below):
let subSvc = generateSubSvc svc (fun doc -> doc.Contents[0]) (fun f -> fun oldDoc -> { oldDoc with Contents[0] = f Contents[0] })
let viewModel = new SomeDocObjViewModel(docObjSvc)
new DocObjView(viewModel)
Now, imagine a modification command now deletes a DocumentObject from MyDocument. The top-level MailboxProcessor now echoes the change to IMainWindowViewModel using it's IEvent<MyDocument>. And here's where my problems begin.
My IMainWindowViewModel doesn't really know which DocumentObject has been deleted. Only that there's a new Document and it has to deal with it. There may be ways of it figuring out but it never really knows directly. This can force me down the path of having to either re-create all the Control's for all DocumentObject's to be safe (inefficient). There are additional problems (such as dangling subSvc's) which I also haven't mentioned here for brevity.
Normally, these kind of dynamic changes would be dealt with something like an ObservableCollection<DocumentObject> which is then mapped into an ObservableCollection<Control>. This comes with all the caveats of shared mutable state and is a little 'hackish'; however, it does do the job.
Ideally, I'd like a 'pure' model, free from the trappings of PropertyChanged and ObservableCollections, what kind of patterns in F# would satisfy this need? Where is it appropriate to draw the line between idiomatic and realistic?
Have you considered using the Reactive Extensions (and Reactive UI further down the road) for the purpose of modelling mutable state (read: your model properties over time) in a functional way?
I don't see anything wrong technically to use an ObservableCollection in your model. After all, you need to track collection changes. You could do it on your own, but it looks like you can save yourself a lot of trouble reinventing the observable collection, unless you have a very specific reason to avoid the ObservableCollection class.
Also, using MailboxProcessor seems a bit overkill, since you could just use a Subject (from Rx) to publish and expose it as an IObservable to subscribe to 'messages':
type TheModel() =
let charactersCountSubject = new Subject()
let downloadDocument (* ... *) = async {
let! text = // ...
charactersCountSubject.OnNext(text.Length)
}
member val CharactersCount = charactersCountSubject.AsObservable() with get
type TheViewModel(model : TheModel) =
// ...
member val IsTooManyCharacters = model.CharactersCount.Select((>) 42)
Of course since we're talking about WPF, the view-model should implement INPC. There are different approaches, but whichever one you take, the ReactiveUI has a lot of convenient tools.
For example the CreateDerivedCollection extension method that solves one of the problems you've mentioned:
documents.CreateDerivedCollection(fun x -> (* ... map Document to Control ... *))
This will take your documents observable collection, and make another observable collection out of it (actually a ReactiveCollection) that will have documents mapped to controls.

C++ with .NET: updating chart via timer

I have some C++ code that performs calculations and I would like to visualize it.
I'm using windows forms (.NET).
The idea is to perform calculations in C++ and to include .h with chart.
As I need fast update, I use timer. As my data is in C++ I should use some tricks to draw it from .h. I was advised to use BeginInvoke() method, here's my proto code from header:
System::Void ActionD ()
{
for (pts = 0; pts < arrlength; pts++) {
chart1->series1->Points->AddXY(test_array_x[pts], test_array_y[pts]);
}
}
private:
System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
MethodInvoker^ mi = gcnew MethodInvoker(this,&ActionD);
chart1->Invoke(mi);
//check if timer works:
Beep(300,500);
}
I have some errors: "...MethodInvoker: a delegate constructor expects 1 argument"
Question is if the general concept of code correct and how can I fix that error?
The C++/CLI compiler in older versions of VS don't produce a very good diagnostic for bad delegate constructor calls. The issue is with &ActionD, it needs to be a fully qualified method name, like this:
MethodInvoker^ mi = gcnew MethodInvoker(this, &Form1::ActionD);
Replace "Form1" with the name of your form class if necessary.
And no, the general concept is not correct. You are using a regular Winforms timer, there's no need at all to use BeginInvoke since the code already runs on the main thread. Nor would you be ahead at all by using an asynchronous timer class, it doesn't make the code any faster.
You make your chart fast by filtering the data, only keeping the Points in the series that you actually need to get an accurate chart drawn. Which doesn't take a lot of points, a few hundred up to a thousand is more than enough. Monitors don't have a lot of pixels so using multiple thousands just keeps the Chart control busy for no benefit. Doing that filtering in a worker thread is the way to get ahead.
I've found a little bit similar topic:
How can I update data in a chart in execution time (in C++ builder)?
So I'm doing this inside my timer:
System::Windows::Forms::DataVisualization::Charting::Series^ seriezz1 = chart1->Series[0];
seriezz1->Points->AddXY(test_array_x[pts], test_array_y[pts]);
It compiles, but crashes at start :(

What will the difference be between instantiating a form and assigning to a variable vs. simply instantiating?

I have a windows form that doesn't have any events or properties I wish to access from the owner. There are two ways I can open the form:
frmExample ex = new frmExample();
ex.ShowDialog(this);
and
(new frmExample()).ShowDialog(this);
Will there be differences in terms of memory allocation and such? Are there any implications, pros and cons? Personally, possibly naively, I prefer the second approach.
Thanks
One big difference is that you won't be able to Dispose() the form instance. You should, disposal is not automatic when you call ShowDialog(), only when you call Show(). Boilerplate code is:
using (var dlg = new frmExample()) {
if (dlg.ShowDialog() == DialogResult.Ok) {
// Access dlg properties
//...
}
}
You can perhaps see from this snippet why the form doesn't get disposed automatically. It would risk generating ObjectDisposedException when you access the properties. You have to dispose it yourself after you're done accessing the properties. The using statement makes it automatic and exception-safe.

Resources