why use BeginInit() with simple BitmapImages? - wpf

I have seen a lot of these on the web:
var b = new BitmapImage();
b.BeginInit();
b.UriSource = new Uri(myPath, UriKind.RelativeOrAbsolute);
b.EndInit();
myImage.Source = b;
now, as far as I'm concerned, I would first have gone for the more compact version:
myImage.Source = new BitmapImage(new Uri(myPath, UriKind.RelativeOrAbsolute));
is there any reason why I should write the first one instead of the second one?
what is it exactly that "BeginInit()" and "EndInit()" do in this case, that would not be done in the second version?
I'm guessing "nothing", but then again, I've had enough experience showing me that WPF is a lot more subtle than I would have thought it is to not wonder...
edit: Just to be clear, my point is NOT that I absolutely want to spare 4 lines of code. I'd rather like to know what those two methods do, exactly, and the reason they should (or should not) be called.

I think they do this, just to be consistent with other code. BitmapImage have several properties, that have to be set only once before it load the image. For example DecodePixelHeight and DecodePixelWidth.
In order to set them correctly, you have to use BeginInit way. And of course, when someone shows examples, they just use the same syntax they are used to, and only remove lines of unrelated properties.
If you don't need to set any of them, you may brief syntax.

The fact that the two methods can only be used in pairs and throw an InvalidOperationException tells me that they stall the initialization of the BitmapImage. Any property initialization between the two methods will be made before the BitmapImage is initialized.
And as I said in the comment,
I guess there is no problem here because you have a handy constructor which takes the Uri as a parameter.

Related

opencascade migrating from AIS_DimensionOwner to PrsDim_DimensionOwner

AIS_DimensionOwner class is deprecated and PrsDim_DimensionOwner is the new one. Iam migrating old code from 6.5.0 to 7.6.0.
before I had:
Handle(AIS_DimensionOwner ) own1 = new AIS_DimensionOwner (this ,7);
own1->SetShape(mySShape);
and now:
Handle(PrsDim_DimensionOwner) own1 = new PrsDim_DimensionOwner(this, PrsDim_DimensionSelectionMode::PrsDim_DimensionSelectionMode_All ,7);
but the second line above, I didn't find an equivalent
I would appreciate any suggestion
It is important to mention from which OCCT version you are porting legacy code to which new one.
According to git log, AIS_DimensionOwner::SetShape() has been removed in OCCT 6.7.0 in '2013 by 0024133: Development of improvement of dimensions implementation; new length, radius,diameter and angle dimensions.
I cannot find direct description, but it looks Shape property has been removed as irrelevant and unused. So that the main thing to pass is appropriate enumeration value to class constructor and second line could be just removed, if no further application code reads Shape back. Otherwise, you may make a subclass and add this property on your own.

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.

InvalidOperationException in Fsharp.Core.dll

So I am doing a simple personal project in winforms with F#. My code used to work, but now throws this exception for seemingly no reason.
An unhandled exception of type 'System.InvalidOperationException' occurred in FSharp.Core.dll
Additional information: The initialization of an object or value resulted in an object or value being accessed recursively before it was fully initialized.
The code is a member method that is being invoked from the constructor of the form itself
do
//lots of other constructor code before this point
// render the form
form.ResumeLayout(false)
form.PerformLayout()
form.ReloadGoals
//several other members before here
member form.ReloadGoals =
let x = 10 //crashes on this line
The website where I grabbed the template for the project I am using is this one.
Unfortunately I have made some substantial additions to this.
I would be glad to post more code, but I need to know what code would be relevant exactly, as I am not exactly sure and don't want to bog down the post in extraneous code.
Also I can't really find a lot of documentation on System.InvalidOperationException.
Every time I find it, it is being used as an example of an exception you can throw on your own, not what causes it.
See The F# 3.0 Language Specification (final version, PDF), §8.6.1 Primary Constructors in Classes:
During construction, no member on the type may be called before the last value or function definition in the type
has completed; such a call results in an InvalidOperationException.
Almost certainly, your code in the question doesn't tell the full story. If you hit the above
mentioned restriction, then there's somewhere an attempt to access a field or member not fully initialized.
Some example:
type X() as this =
let x = this.X
member __.X = 42
X()
One workaround might be to encapsulate the offending code in a member of its own and call that in the constructor instead. Another would be the wrapping in a function definition.
This will be an incomplete answer, since I cannot reproduce the problem (using F# interactive, the given example, the ReloadGoals modification, and Form.Show, the code runs fine). However, there are strange things happening:
Taken from the template, there should be a handler method for the Form.Load event, which fires when the type is fully constructed. Why is additional loading code in the constructor instead of this event handler? Load exists precisely to counter this kind of problem with unorderly initialization.
The template you are using isn't exactly sane F#. For example, initControls is a value of type unit that is evaluated where it is defined; its binding to a name is absolutely useless and should be replaced with a simple do. Writing initControls in the do block later has no effect at all. form.ResumeLayout(false); form.PerformLayout() should be equivalent to form.ResumeLayout(true), but I don't understand what these are doing in the constructor in the first place. The event handlers have two possibly unnecessary indirections: one to a delegate constructor, another to a method that has no real reason to exist -- the handlers should be lambdas or simple, private functions. Why are they public members?!
The error appearing in the question is probably caused by the usage of form in its own constructor. Move your new usage to the Load event handler, and it should work.
Personally, I would go further and ditch implementation inheritance by instantiating a plain Form and subscribing to its events. For example, in FSI, something similar to the template could be done like this:
open System.Drawing
open System.Windows.Forms
let form = new Form()
form.ClientSize <- new Size(600, 600)
form.Text <- "F# Form"
let formLabel = new Label()
formLabel.Text <- "Doubleclick test!"
formLabel.DoubleClick.Add <| fun _ -> form.Close()
form.Controls.Add(formLabel)
form.Show()
which uses no inheritance at all. (In an application, you'd use Application.Run etc instead of form.Show().) This does not run into initialization problems as easily and, additionally, is very useful if you want to encapsulate the form inside a simpler type or even just a function.

WPF app with multiple usercontrols

I Am creating simple WPF test project which contains multiple UserControls(Insteda of Pages).I Am using Switcher Class to navigate between different UserControls.When i navigate to different pages,i have observed that memory consuption keep on increasing on each UserControle Navigationand GC is not invoked.
1.So am i doing something wrong in following code?
2.Which part of the code consuming more memory?
3.Do i need to invoke GC for disposing my UserControls on each new UserControle creation?
If need how can i invoke GC?
public void On_Navigate_Click()
{
UserControle newusercontrole=new UserControle();
DataSet ds = new DataSet();
ds=con.getSome_Datafrom_SQL();//Gets data from SQL via connection class
dataGrid_test.ItemsSource = ds.Tables[0].DefaultView;
Grid.SetColumn(newusercontrole, 1);//dataGrid_test is inside newusercontrole and following is the code to add "this" usercontrol to the main window.
Grid.SetRow(newusercontrole, 1);
Grid.SetZIndex(newusercontrole, 10);
Container.Children.Add(newusercontrole);
}
First off, I must point out that if garbage collection really isn't happening (as you said), it's not your fault and it does not mean you're doing something wrong. It only means that the CLR doesn't think that your system is under memory pressure yet.
Now, to manually invoke a garbage collection cycle anyway, you can use the GC.Collect() static method. If a garbage collection actually starts and your memory consumption is still unreasonably high, this means that you're probably doing something wrong: You're keeping an ever increasing number of unnecessary object references and the garbage collector cannot safely collect those objects. This is a kind of a memory leak.
As far as your code goes, I think that the problem is at the end of the method you posted:
Container.Children.Add(newusercontrole);
This seems to add a new object (on every click) to the collection Container.Children. If this is not removed elsewhere, this is probably the cause of your memory leak. I don't know what the suitable solution would be for your use case (since I don't know exactly how your UI should behave), but you'll likely need to find a way to remove the last UserControle added from the Container.Children. If you can use LINQ, then the methods OfType<T>() and Last() could be of use to find it.
In any case, don't leave the GC.Collect() line in production code. Use it only to force a collection cycle for testing purposes, like this one.

Does it make sense to Freeze a Geometry/Brush even if I only use it once?

Example:
If I create a Geometry inside a OnRender method and it is never used elsewhere like so:
protected override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
var geometry = new RectangleGeometry(new Rect(0, 0, 100, 100));
geometry.Freeze();
dc.RenderGeometry(Brushes.Red, null, geometry);
}
Does the Freeze() call here still make any difference?
It depends. Freeze will make your code faster, since WPF will not care about lot of stuff any more, as freezed object cannot be modified. So if your code uses some objects frequently and it's performance issue, then you should try freezing it. On the other hand - if code is not giving you any performance problems at all, then you probably shouldn't care about freezing it (you know, premature optimization is root of all evil).
You could also use Freeze when you want to make sure, that nothing should be able to modify your object. This way, you can guarantee, that values you've set before freeze will be the same all the time. But this is dependent on your requirements.
You should also check this to get some basic idea over freezing objects and then it may become clearer when to freeze.

Resources