I am working on a WinForms project which feels sluggish. It is composed of a literally hundreds of User Controls. If there is a piece of a UI functionality (even if not used anywhere else in the app), it's encapsulated in a User Control. I've gone through the project a number of times with the ANTS profiler and most of the heavy code appears to be in various control constructors.
Before I start ripping out User Controls, do they represent significant overhead to a WinForms application versus just laying out the form without User Controls (e.g. just intrinsic controls)?
A user control is a container for other controls. Having hundreds of them probably means you have multiple hundreds of windows in your project. A window is a very expensive operating system object. They start to noticeably drag down painting perf when you have more than 50 or so.
The comparison to Outlook is apt. That's a good sized chunk of a program. It has less than 50 windows. Easy to see with Spy++.
The difference is OnPaint. Microsoft wrote a lot of code, they didn't drop a lot of controls on a form.
I've been in User Control hell and it's not fun. A few things I've noticed:
If you have too many user controls and move your form around or scroll, you can wind up with a lot of white flickering as the drawing operations of deeply nested window handles fight for rendering time. This is particularly noticeable when you first open up the form.
Beware of nested user controls in the designer. If you open a user control in the designer, the constructor won't be called (it actually generates the designer surface by parsing the compiler-generated code.) However, user controls used by that user control will have their constructors called. This is usually not a problem, but it's worth knowing about if you see odd things happening.
If you have a large solution with lots of user controls, VS 2008 will take a long time to enumerate all of your projects to find all possible controls the first time you open the designer pane. This is a relatively minor annoyance, but it can consume time.
That said, User Controls are definitely handy and worth using in moderation. The main thing I try to avoid is overly deep nesting. I've found that WPF is much better in this respect. It has full control over the rendering pipeline, so you don't get the repainting issues associated with deep composition of controls.
Related
I have a WinForms application. the main form is has a lot of controls and that is one of the reasons that makes it load very slow. what I would like to do is to make the form load faster.
I have set the beginupdate and endupdate. The form is not being rendered in the background worker thread, because this is the main form. There are no initial forms. When the user clicks the application icon, this is the first form that loads up. Adding a progress bar or any splash form is not a good idea for me.
I have checked other questions here on Stack overflow but they do not seem to face the same problem as I do.
If there are some examples/ideas you have in mind, it would be nice of you if you can share it with me.
A few suggestions:
Try to minimise the complexity of your UI. Your users will thank you and you'll have fewer controls to load. For example, if you have 3 or 4 controls that are not used often, can you move them into a dialog or fold-out "advanced" section of your form, so you can defer creating/showing them? Are all the controls needed? Really? Think about the workflow you are trying to achieve - is the current set of controls the simplest way to achieve the workflow? DO all the controls need to be shown at once? Perhaps you could place them on to separate tabs in a tab control (and thus only actuallyl create the controls as the tab is shown)?
Can you reduce the range of control types used? Each new type of control may cause your program to load up a new dll to support it. Every dll that has to be initialised causes extra startup time.
Are you using any controls that are slow to start up? A simple text field will be fast, but a complex graphing control may be slow.
How many assemblies (of your own) are loaded? Combine all the code into a single assembly (e.g. with ILMerge) and load times will probably improve quite a bit.
Remove any initialisation code that isn't needed. Can you simplify the initialisation? Can any initialisation be deferred (e.g. only create some member variables when the user clicks on the first button that actually needs that data to be present, Don't try to create a connection to a database if it's not actually needed yet, etc)
Can you defer creation of (some of) the UI? For example, you may be able to place a group of controls into a separate UserControl form, and then add this form programmatically to your MainForm shortly after startup (e.g. on a Timer). This will allow your MainForm to appear very quickly, and then be "populated" shortly after with additional controls, which may not improve the actual startup time, but it will "feel" a lot faster and more responsive to start up. (This approach can also be extremely effective if your MainForm scrolls and those extra controls are initially not on-screen, as they only need to be created if the user scrolls down enough to see them)
Are you displaying any information that might be slow to load (e.g. large bitmap images or data fetched from an SQL server)? Can you defer the loading of them or run it as a background thread? Use compression to speed up loading? Reduce their resolution to minimise the amount of data that must be loaded? Pre-process data and store it in a quick-start cache for the next time the program is run?
Can some controls be replaced by an optimised approach? e.g. You can create a "button bar" as a set of 10 separate controls, or as a single control that draws iself with the appearance of 10 buttons. It's much easier to make the single control initialise and redraw faster than 10 separate controls.
And of course, once the most obvious low-hanging fruit has been collected (or even before):
Run the program under a profiler and see where it's spending its time.
Try to minimize the code that executes during on load of main form or any of the control that is placed on the main form.
You can also explore NGEN which is Microsoft's tool which helps in improving managed app's performance
When a form loads it initializes all its controls.
The Form itself isn't taking you a long time.. It's your controls.
Go over your controls and check what can be improved in their constructors and initializers.
Do you need all of the controls immediately? If not perhaps you could load them programmatically after some event fires that lets you know you need that control.
If you have several controls to a parent control, call the SuspendLayout method before initializing the controls to be added.
After adding the controls to the parent control, call the ResumeLayout method. This will increase the performance of applications with many controls.
For example:
private void LoadData()
{
// Suspend the form layout and load the data
this.SuspendLayout();
LoadMyData(); // logic to load your data will be here
this.ResumeLayout();
}
EXPLANATION:
SuspendLayout() - Stops the layout object from being updated and thus the component does not spend any time making calculations for repainting until the layout is resumed.
ResumeLayout() - Recomputes the layout once after all of your changes are made, resulting improvement in performance.
Why use SuspendLayout() and ResumeLayout()
It prevents layout accidents when controls have layout properties that affect each other.
It adjusts multiple layout-related properties like Dock, Auto-Size etc.
I have a WPF application, and it's slow.
It is NOT the rendering. Firstly, the rendering is quite simple, and secondly, I looked at it with WPF Performance Toolkit - nothing.
It is NOT in my own code. Firstly, the unit tests work fast, and secondly, if I replace all DataTemplates with blank ones, everything works fast.
So far, it looks like the slow part is template instantiation. That is, when you start the application, and open some complicated screen, it takes a lot of time. And by "a lot" I mean "a lot". Sometimes can be as much as 3-5 seconds - for example, when there's a datagrid with 100 rows. But when you go to another tab, and then go back to that same screen, it opens fast (as long as its viewmodel stays put).
This is very annoying not just because it's slow, but because I can't do anything about it. If I had some control over the slowness, I could, maybe, display some "opening, please wait" message or something...
Besides, when I look at some other WPF applications (most notably, ILSpy), they seem to work reasonably fast, despite the large amounts of data. This makes me believe that I'm probably doing something wrong. But I have no idea where to start.
Any ideas? Any classic mistakes? Any tips?
My exerience comes from working on the WPF mind mapping application NovaMind
A couple of months ago we completely rewrote our intermediate layer to solve the performance issues we had experienced. In a nutshell, creating our user controls seemed to be way to slow. Unfortunately I couldn't find a great way to profile the performance as neither the WPF Performance Suite nor commercial applications such as ANTS Profiler give you any detailed information on this part of the WPF process. (I asked this question back then)
We resorted to manually test our application by trial and error and removed parts of our user controls to see what exactly is the culprit.
In the end we solved the performance issues by completely rewriting our controls. We also cut down on the complexity of our visual tree dramatically. Before the rewrite, one of our most used user controls, when inspected with Snoop, consisted out of 61 different things, now there are only 3. Wherever possible we only added things to the visual tree on demand. (As you know in XAML even when you set things to Collapsed, they need to be created first).
Finally we were forced to write our own rich text rendering control as the built in RichtextBox is ridiculously slow and the visual tree of the RichtextBox is quite complex.
I don't know if this will apply to your situation but I would recommend that you investigate your user controls and see if they are complex. Maybe you have things that you could trim.
Low hanging fruits would be parts that are only rarely visible or can be created in a lazy manner. You could create these parts from code behind when necessary rather than having them in XAML. This should help you a lot.
Otherwise virtualization is your friend, if possible. In our case we couldn't do that unfortunately.
This sounds similar to a problem i was having. I posted the fix here: WPF UI Automation issue . Just posting for the benefit of searchers, as it took ages to resolve.
Following comment on link only answer, here is the crux of that post:
I did the following:
Downloaded Hotfix - - http://archive.msdn.microsoft.com/KB978520 (may not be required)
Downloaded Hotfix - - http://archive.msdn.microsoft.com/KB2484841 (definitely required even if you have Windows 7 / .NET 4)
Improved the code further (the validation was causing an excess of objects) - Why does WPF Style to show validation errors in ToolTip work for a TextBox but fails for a ComboBox?
It may be that only Number 3 was required, but it worked. Just posting here so people dont lose the days I lost in memory profilers etc.
User Control in your data template, is not completely bad idea but if you crave for performance then you should consider switching to lighter control. For example, having a UserControl just hosting a TextBox is very bad idea, as UserControl is made up of ContentControl, ContentControl hosts ContentPresenter and ContentPresenter will host TextBox so if you notice your Visual Tree, it has three new layer of UI Elements. Reducing Visual Tree will certainly improve the performance.
Most likely, I would suggest creating Custom Controls that may be a completely a new control having few dependency properties that can relate to data you want to present and you can have its own custom template in generic.xaml. Second, you can just simply derive a control from existing controls and redefine its default template in generic.xaml.
This approach will certainly work better as you will be reducing your Visual Tree, thus reducing Visual State Manager's job.
Changing theme or template will be slower then changing the element that hosts content. And let the element have the default template in its own generic resource dictionary.
Try moving all the resources up as
far as they'll go, preferably into
app.xaml
Check if you could use StaticResource
instead of dynamic ones, static ones
are alot faster
If possible, try using depedency
properties in your VMs, especially if
you have alot of them at once or if
they have alot of properties. That will keep wpf from having to do a bunch of reflection.
You mention you are using a DataGrid with, say, 100 rows. A likely culprit of your perf problems is that whatever datagrid you are using isn't doing virtualization, and so your visual tree is gigantic.
Normally, long startup time in WPF screens points to a large visual tree.
I'm not sure if you're using a datatemplate per row, or some 3rd party grid that binds columns, or what - but lets say you have 8 columns with controls. Depending on your grid/validation/etc, this could be a visual tree of 20-60 items per row. If you have a combobox, then each item in the dropdown may be created per row as well.
To fix this just takes watching the details, and taking measures as you go:
Use a virtualizing control as much as possible. This means using a virtualizingstackpanel inside list controls, and making sure your 3rd party controls do as well (many stock WPF controls do now by default)
Do not overuse UserControls, composite controls, etc. Adding depth adds time, and putting in extra visual tree depth in a datatemplate or other repeated area adds up fast.
If all else fails, show a simple screen and add controls through code to improve perceived performance
I have a WPF application (.NET 4) which has a main window, and inside that main window shows many smaller UserControls. Various actions performed by the user cause the UserControls which are displayed to get replaced by different other controls with different data.
I am running into performance problems however, when switching these controls. The WPF dispatcher thread goes to 100% CPU while loading controls. On older machines, or with larger numbers of controls, this can result in the application appearing to lock up for as long as 30 seconds!
Profiling indicates that almost all of this CPU time is spent calling the various InitializeComponent methods of all the different UserControls - no one control appears to be vastly worse than any other, they all seem to take between 0.2 and 0.5 seconds (on my dev machine with a fast processor and good graphics card).
As far as I know, InitializeComponent is where WPF actually loads the compiled xaml into memory.
I'm at a loss for what to do here. I'd like to pre-initialize things on a background thread, but all WPF controls must be created and used on the dispatcher thread, so I don't think this is possible.
Otherwise it looks like the only options I have are to delete all my xaml??
Any help would be greatly appreciated
To revisit this - we do have many complex controls on the screen, but we can't just get rid of them to keep WPF happy!
Further experimentation with profiling showed that using Custom controls (basically just a C# class deriving directly from Control and defining the UI in a Generic.xaml themes file only seem to incur the hit of loading and parsing the XAML once. Thereafter, each control just applies the pre-existing theme.
Custom controls are much more difficult to work with than UserControls, but this did seem to help our load performance a lot.
The InitializeComponent method takes time because it needs to insert the control in the Visual/Logical tree and assure all bindings, themes, expected resources etc.
My only suggestion is - is it possible to initialise all potential controls from the outset, and then show/hide them when needed using the Visibility property ?
You can use Freezable for caching some UI, but if they are user controls then most likely you will want your user to interact with them.
For the record, I had a window with a load time about 1500 ~ 2000 ms, the problem was the icons.
I was using a tool for converting SVG to XAML DrawingImage elements, and a user control with a large resource dictionary with a drawing image for every used icon
The InitializeComponent was so slow because it had to parse that large XAML file containing all the vector data for the images
Hope it helps.
Facing an issue where in the user objects goes more that 10000 in windows app and the app crashes.
After much analysis we realized that we need to get rid of the panels that we use to align the controls and may be reduce the possibility of user objects reaching 10000.
Our App UI is dynamically generated driven by a configuration and it can vary. So all the UI generation is happening dynamically.
Any help would be much appreciated
This is an unfounded suggestion, but remember to make sure that unneeded Controls always detach themselves from events they are be subscribed to. A Control that's still subscribed to an event of an "active" (what's the right term?) object can't be cleaned up.
Just as a note, the Chrome development team hit this problem too, and the scroll bar arrows (among other things) weren't drawing anymore when some internal gdi limit was hit. It is quite possible to hit this limit in a complex enough gdi app.
You might want to do some research and see how they fixed it.
As an alternative, you could consider using a different platform, either gtk or wpf would do fine and they don't use gdi handles to draw.
from here,
If your program runs haywire, you will
find that it manages to create about
10,000 window manager objects and then
the system won't let it have any more.
Why stop at 10,000?
The first answer is "If you have to
ask, you're probably doing something
wrong." Programs shouldn't be creating
anywhere near ten thousands window
manager objects in the first place.
There is no need for that many handles. I think you need a new solution.
I'm guessing this from your question, but you're probably putting this large number of controls on a scrollable panel or a tab control with multiple tab pages, which means that most of these controls aren't actually visible to the user at any given point in time (because they couldn't possibly all be visible at once).
If you have all of these controls on a scrollable panel, one possible solution is to only load and display the controls that are on the visible portion as the user scrolls around in the panel. As the user scrolls, you would unload and dispose the controls that are no longer visible.
If you have all of these controls in a multi-page tab control, you can use a similar strategy and only load the controls on a tab page when that page is made visible (and unload the controls from the previous top-most tab page at the same time).
Another general strategy is to break up your one monster form into a large number of UserControls, and only show one of these UserControls at a time.
I'm writing a WinForms based application for Windows Mobile, targeting the CompactFramework 2.0 and coding in C#.
My application has a menu which the user can select severeral job functions from.
My question is this:
For the job specific screens, should I load a UserControl into a panel in the main form, or is it better to open a new form on top of the main form?
They both seem to meet my needs, and I don't know if there is a "right" answer here.
Is one method more correct than the other?
Forms are Controls (just look at the inheritance chain), and a Form itself doesn't have a whole lot of overhead in and of itself. It creates a native Window, but that's about it.
What should drive your decision is how you use and display your UI elements in your solution. Forms are conducive to many UI architectures, and they're what most developers are familiar with. The designer supports them well, and creating, showing, hiding and closing Forms is a well documented, often used paradigm that works just fine. Yes, you have the load penalty whenever a Form is created as it creates all of its contained controls, but you're going to pay that even if it's a UserControl. The child controls have to be created in either case.
One might argue that Forms require that you recreate them every time, but that's not true. If you use ShowDialog or Hide instead of Close, you can reuse your Forms and pay the price once. The advantage here is that the Form holds your Controls in teh collection and manages all of that for you, so you have little to worry about with the GC and remembering what roots you have alive.
The UserControl paradigm is more complex - you have to manage loading and unloading controls yourself to keep memory pressure low. Complexity also increases cost - cost to maintain, cost to support, and likely cost to develop. However there are some clear advantages to UserControls in some scenarios too. If you use an MVC/MVP pattern and some form of framework that handlesyour Views, a USerControl makes a really good View with the Form becoming the Workspace (the SCSF for the desktop is a classic example of this, and so is the OpenNETCF.IoC framework for the CF).
So which is "better"? It depends on how and where you're using the elements, how your team is already doing development, and how you've architected the solution you're plugging in to. In short, the is no one right answer.
In my experience, depending on your hardware, loading controls far outperforms launching distinct forms. Our devices (Motorola WT4090 with 32meg) have no hardware acceleration, and drawing complete forms seems to really tax them. There is as much as 4-6 second delay any time a form is launched; controls, however, are almost instantaneous.
Maybe the best answer is to create a series of user controls and experiment with loading them onto the main form. It should be a fairly easy matter to then try to create a series of forms that have just the user control to see if you can improve performance.
If you don't see any performance benefit either way, it seems that it would just be a matter of preference.
Use Forms. It's the way the other applications behave. It's the way the user expexts your application to work.
Look at the pre-installed "Contacts" application: On startup you get a contact list. Once you select a contact, a new form is being opened on top of the current window. It's showing all the contact's details. Selecting "edit" from the menu will open yet another form, allowing you to edit the contact. The "Tasks" applicatoin behaves just the same way.
So the user knows: Clicking somewhere will open up a new form, and closing that form will get me back to the last form. You should work with that knowlegde rather than against it. When you use a single form, the user might repeatedly close it while he actually wanted to get back to tha last form.
From a performance point of view I find that forms open fast enough (<1 sec) on my WM 5 and my WM 6 devices.
And while it's possible to achieve form-like behaviour with UserControls, it seems more straitforward to use forms when you need form-like behavior.
So my bottom-line is: Use Forms!
P.S.: There's a good article on CodeProject on : How to create MDI Application in Compact framework
Depends on the complexity of the form/Control. Going the UserControl route will provide better performance as you will not have all of the form create functionality to also deal with.
My advice is to create a new Windows Form for every different logical action. If you need a form that is logically independent, then is better to have a separate Windows Form for it.
To speed things up you could construct all your forms in application's start up. This way you will have a delay when your application is launching (most users will be OK with this), but afterwards everything will run faster.