views:

669

answers:

9

How to speed optimize WinForm applications. I am not talking about apparent .NET opt. technics - like ngen-ing, caching objects, etc. Already tried that and what I am up to is to reduce the form initilization time from a 1500 msec down to 500msec.

Profiling has identified the slowest code and almost all of it is in the InitializeComponent, and within this method the slowest lines is

  1. creation of the (just new-ing) WebBrowser component
  2. loading icon from a resource (hideous 500msec)
  3. creation of the ContextStripMenu
  4. several this.Controls.Add() calls contribute a lot too.

At the moment can only see how to fix point (2) - move icon data from being stored as embedded resource to a private field (e.g. base64-encoded string)

but I have no idea what to do with points 1, 3 and 4.

Your ideas would be greatly appreciated!

Thank you.

A: 

The only thing I can think of that you could do is rewrite the controls that you want to use and optimize them to initialize faster (as well as the Form class to optimize adding the adding of the controls to the form).

I can't see how that is feasible though, and I think you are going to be stuck with this, depending on your reliance on these controls.

casperOne
A: 

Can you do lazy loading for your Webbrowser control ? If it's in a tab which is not the main view then you might load webbrowser when that tab activated.

Or you might load the form then load the webbrowser (this might help you to show something first then show everything, just like you'd do in a website)

dr. evil
Thank you. I would give it a try.
Though the downsize would be I would have to sacrifice using VS form editor.
+2  A: 

If this is not the main form, create the form as hidden in another thread and show it right away when user asks for it.

If it's the main form you can still initialize the controls in parallel using multithreading: webbrowser in a thread, icons in another, strip menu in another etc. But form still needs to be hidden I guess as Window messages in multiple threads can confuse things.

Also you might still need to do "controls.add" part in the main thread as Controls collection may not be thread-safe.

ssg
+1 I like the idea of multi-threaded InitializeComponent. It would sacrifice the VS form editor, though, so I suggest cloning the form, desinging the form's clone, and keeping them in sync.
configurator
Also, the Controls.Add *must* be done in the main thread, after a Thread.Join is done for all initializing threads, because otherwise the different controls would live in a different thread and using them would always require Invoke if I'm not mistaken.
configurator
Process memory is shared between threads, so a memory structure or a code cannot belong to a thread. However threads can conflict in accessing memory of course.
ssg
A: 

Load the icon in a separate InitializeComponentAsync thread.

Justice
A: 

Regarding #1 - there's no way just newing up a WebBrowser component should take 500ms. What properties do you have set on it?

ZeroBugBounce
A: 
  1. Just take another class like “ClsAppearance.cs” as I taken.
  2. Initialize all controls like static Infragistics.Win.Appearance txtBoxMidAppr = null;

I take my own name like txtBoxMidAppr instead if the appiarance1 . due to it can be use for all textbox, by only once initialization.

  1. Make a function where we can initialize the appearance and call it on the MDI/Main form loading only once. public static void LoadAll() { txtBoxMidAppr = new Infragistics.Win.Appearance(); }
  2. Make another function here and take the appearance code from designing window public static Infragistics.Win.Appearance App_txtBoxMidAppr //text_box_small { get { txtBoxMidAppr.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(93)))), ((int)(((byte)(93)))), ((int)(((byte)(93))))); txtBoxMidAppr.ImageBackground = global::CS_POS.Properties.Resources.text_box_small; txtBoxMidAppr.ImageBackgroundStyle = Infragistics.Win.ImageBackgroundStyle.Stretched; txtBoxMidAppr.ImageHAlign = Infragistics.Win.HAlign.Right; return txtBoxMidAppr; }

    }
    
  3. In the deigning code of the form comment all appearance setting of the text box and put the function name for getting appearance from the ClsAppearance.cs class //appearance4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(93)))), ((int)(((byte)(93)))), ((int)(((byte)(93))))); //appearance4.ImageBackground = global::CS_POS.Properties.Resources.text_box_small; //appearance4.ImageBackgroundStyle = Infragistics.Win.ImageBackgroundStyle.Stretched; //appearance4.ImageHAlign = Infragistics.Win.HAlign.Right; this.uteNABoth.Appearance = CS_POS.App_Appearance.ClsAppearance.App_txtBoxMidAppr;

take all controls appearance and make a function in the class and call it from there.

So the appearance initialization will goes only once and can use many time.

A: 

I have change the strategy of form loading, this will made a great change on form load timing, now it’s take average 37MS instead of 466MS.

Method:- On First time Click on Top-tab/Icon, application load all form under that tab/icon and on click on Form Icon it will only switch visibility. And again visit on Top-tab will not load the form under that tab.

A: 

the above comment working are as follow:----------------------

  1. make a global form object like -Appointment ObjfrmAppointment = new Appointment();
  2. take a bool varieble bool HomeLoaded = false;
  3. on click the top-tab do the following if (!HomeLoaded) { ObjfrmAppointment.Show(); ObjfrmAppointment.Visible = false; ObjfrmAppointment.Location = new Point(0, 0); HomeLoaded = true; }

  4. on click on form icon do the following childForm.MdiParent = this; childForm.Parent = pnlForm; childForm.Visible = true; childForm.SendToBack(); CloseAllChildform(childForm.Name); childForm.BringToFront();

where childform is the form which we want to be load. and the closeallform function make visible false for all other forms. like

public void CloseAllChildform(string frmname) { foreach (Control childform in pnlForm.Controls) { if (childform is Form) { if (childform.Name != frmname) (childform as Form).Visible = false; } } }

where frmname is the name of form to be loading.

A: 

One technique I have used in the past was to multi-thread the data load, so that it runs simultaneously to the form creation. In this instance data was being loaded out of AD, it cut about 1/3 of the load time.

benPearce