views:

153

answers:

6

My form has over 200 control(s)! It takes about 7 seconds to load the form and bind the controls.

I've traced the application with some performance profilers , but I didn't find anything with HOT flag except the constructor's of form.

I would like to know that is it possible to call InitializeComponent method with sth like backgroundWorker (multithreading) !?

+8  A: 

No, threading will not help you. The controls need to get created on the UI thread for the application to work at all.

The only reasonable way would be to look into whether you really need to create all 200 controls when the form is created, or if you can perhaps have them load "on demand".

Without knowing your application it's impossible to give more concrete guidance, but perhaps you have a situation where not all controls are in use at the same time, but rather that there is some sort of paging. If that is the case, each "page" could perhaps be made into a user control, so that you can load and unload pages as they are needed.

Fredrik Mörk
+3  A: 

Performance isn't your only problem. There are OS limits on the number of handles a process can own, and there are limits on the nested control layout WinForms will perform. If you have 200+ Windows Forms controls on a single window, I'm betting you're going to run into these and other limits.

I recommend changing your Form so that there are fewer controls: paging, virtualization, lazy loading are some techniques you can use to improve your UI and your performance.

Judah Himango
+6  A: 

A better idea would be to split your UI up using a TabControl. It has lazy loading built in.

Per MSDN :

Controls contained in a TabPage are not created until the tab page is shown, and any data bindings in these controls are not activated until the tab page is shown.

And that design is directly aimed at your problem.

Henk Holterman
Does it really lazy-load?? I doubt... but I do not know, better check now.
Aliostad
With 10 controls per tab, that's 20 tabs.
BoltClock
@Aliostad: Yes it does. See [MSDN](http://msdn.microsoft.com/en-us/library/system.windows.forms.tabcontrol.aspx) : Controls contained in a TabPage are not created until the tab page is shown, and any data bindings in these controls are not activated until the tab page is shown.
Henk Holterman
@BoltClock, With TabControls on TabPages the problem goes down quickly. It's a O(log n) problem.
Henk Holterman
@Henk: good point.
BoltClock
@Henk: Thanks mate.
Aliostad
+1  A: 

I believe NGen-ing your application can help the performance a lot. Most of those controls (some of them possibly custom in your application) need to be NGen-ed and that usually takes a long time, as going back to the same form is always much faster.

Aliostad
I didn't try but 7 seconds smells more like a data(base)binding issue than a JIT delay.
Henk Holterman
Well, it seems to be windows forms and not WPF so not sure if he is using data binding.
Aliostad
A: 

While I might agree with Judah, I have seen plenty of forms in an MDI WinForms app that far exceeded 200 total controls logically contained in a form, and the form needed every one of them to do its job. An invoice entry window for instance would have a set of controls for a header, then a set of user controls that each mapped to an invoice line and had fields for SKU, description, quantity, unit price, extended price, unit tax, etc. Such a window's control count depends on the number of invoice lines, and a large order can generate an invoice requiring thousands of controls to be bound and rendered on a single screen if done naively. Add in further per-line detail for shipping instructions, tax information, backorder status etc. and attempting to pre-load and render every control on window load would crash the application.

7 seconds seems excessive, though. I agree with Frederik; the first step is to look and see if all 200 controls have to be rendered in order to show a single screen's worth of information. Using tab controls, with event handlers for tab changes that "lazy-load" the information and controls shown on each tab, is a good first step. If you show lines of repetitive child information (like invoice lines on the invoice) you can save time by loading a finite page of information at a time; loading 10 lines is far cheaper than loading 100, and while there is some overhead in talking to a DB and dynamically loading controls that will be repeated more often this way, it will seem trivial compared to waiting several seconds just to see ANYTHING load on the window.

KeithS
+1  A: 

Things to try that others haven't mentioned:

  • Take the [DebuggerStepThru] option off of InitializeComponent, then you may see which items are taking long more easily (w/ profiler or just randomly hitting 'pause' in the IDE during load 20x and remembering where it stops most).
  • Convert to WPF if your boss will let you.
  • Take the forms InitializeComponent's items, outof initialize component and on clipboard. Add a timer w/ 20MS ticks. On tick, increment a counter. Add one control per tick, by splitting your initializecomponent code into a 200-case select statement. At 201 stop the timer. That way the user can start working before all the controls are added. You will have to rearrange the controls.add so they show up. You will have to show the important controls first. You will not be able to modify your form in the designer. Lastely, I pity the foo who thinks this bullet point is anything but a joke.
FastAl