Ensure smooth Storyboard animation when UI Thread is blocked - c#

In my WP8 application I have a UserControl with an active Storyboard animation that makes that UserControl to move in a desired direction. At some point during that animation I programmatically add second UserControl to the scene.
The problem is that second, dynamically added UserControl contains a lot of elements inside and takes substantial time to render. While it loads, the UI is being blocked for about 50 milliseconds on my phone and the glitch in first UserControl's Storyboard animation is very noticable.
Question is what can I do about it? Should I somehow run animation in a different thread? If so then some general examples/links/manuals will help a lot because I'm not too versed in threads business. If that's not an option then I'd like to hear whatever can help me here.

I wouldn't advise threading on windows-phone; also you should avoid threading if you have data that needs to be shared between threads. It can be done but it's not easy.
If possible I would pre-load your user controls (or group of controls) and then show/hide them as they are needed. That should prevent the glitch you are seeing. If you need help with how to preload please post some example of how you are dynamically loading your controls and we may be able to assist you.
If you do need to do multi-threading I would advise using a background worker more details here:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/cc221403(v=vs.105).aspx

Related

Dynamically adding lots of Controls form another thread

I am learning multi threading in Win Forms using C# and according to sources the best way to achieve this is by invoking the main method from worker threads.
Now this all works good when heavy processing must be done and THEN the GUI is updated.
However I have a scenario where I need to programmatically add lots of controls inside a panel. This may go up to thousands (panel will be scrollable). Hence, since the controls are ultimately being added by the main thread, the program still hangs until this has been completed.
Is there any way around this? Or should I try and use some other control which doesn't require me to instantiate lots of controls simultaneously (as this is obviously a bit heavy).
Basically this panel contains a list together with an icon (depending on the state). Hence I am creating a label for every entry which I do not know if it the ideal way.
By the way I come from the web applications development department... Is there a control similar to a div in .NET? I looked at a rich text box but it doesn't seem to let you add an image in a straightforward way.
Thanks in advance.
You shouldn't have a good reason to add hundreds of controls, let alone thousands. It sounds like you need a custom control and you need to add items to it.
The ListBox or ListView control will work for a basic item but if you want lots of customizability you will have to reinvent the wheel yourself and draw everything manually. It's a lot of work if you need to handle multiselect, scrolling, keyboard shortcuts, etc.
This is the strength of using WPF instead of Winforms since you can easily use the existing ListBox logic and have free range to customize the appearance of the items and even how they are arranged.
WPF has the concept of a virtualizing panel which can perform well even with thousands of items since it doesn't create the UI objects until an item is scrolled to.

C# Object Creation Takes Time

I need to create about 720 buttons or labels in my application during run time.
The problem here is when I start my app or make it (re-)visible, I can see that
buttons being loaded.
How can I avoid from it or make it faster?
The best way is to use Control.SuspendLayout Method before you've started to fill your control with buttons and than Control.ResumeLayout after you finished
You could try suspending the layout before loading the controls, and resuming it afterwards. This should speed the loading: SuspendLayout
Here's a link which might prove useful reading: (tips on improving wndows forms apps performance) -
Winforms performance
It's hardly possible that you need all that buttons at once.
If ou're designing UI, split it in tabs, where tab rapresent UX logical groups.
If you're not designing UI, using control is not a good option, choose something else to draw on the screen and it will be much faster.
There are some good tips here you can go through to speed up your application.
http://devcomponents.com/blog/?p=361
That said, I would really raise a question on why exactly you need to load 720 buttons. There's a very good chance that you will only be using say 5% of the available controls on your form. Find out a good way to reduce them.
If you like to "hide" the process of loading all the controls just use a splash screen so the user can see that the application is loading but cannot see all the actual components until the loading is done.
PS: Think about splitting those buttons in groups because im sure you dont need all of them at one place(maybe split in tabs? and load them when the tab is pressed?) Well just think about it.

Concurrent data loading with winforms

So my problem is this. I have a form with a panel in it. This panel serves as the container for multple different usercontrols, of which only one is visible at a time. Some of said usercontrols display a lot of data from the DB, so loading them takes a little bit of time (the data is shown in a bound datagridview). I tried creating a LoadData-method for these controls that I then launch in separate threads and once they've done their work, they enable the actual buttons on the main form for displaying them.
There were, however, many different problems. First, I can't call this.Invoke on the usercontrol until its handle is created, which seems quite hard to force, especially if I want to show a splash screen during the initialization (the main form's handle isnt created yet).
I did manage to force this by setting the form.Visible = true and then calling form.CreateControl followed by form.visible = false. This does, however, show the form blinking on the screen which doesn't look nice.
I also tried not using Invoke if the handle is not yet created, but this brings me to the problem of my data object being created in a different thread and then not being accessible for the control's "normal" thread.
So as is probably quite obvious, I'm quite lost when it comes to multithreading, especially so with winforms, and even more so at the launch of the application. My explanation might also be rather confusing, but I'll try and clarify if it's needed.
So what is the correct way of doing this?
Hard to know where to start with this.
Can't figure out whether your problems are premature optimistion, or trying to retro fit multi-threading.
If I had say a six buttons and one panel and the buttons flipped a usercontrol in the panel to visible, My thread would return a user control, which I'd then add to the panel and then enable it's related button.
Takes all the synchronisation stuff right out of the equation, and gives you maximum scope for optimistion the getting and setting up of the controls.
Or you could setup all the user controls but not bind them and get your threads to bind on completion, I prefer the former way though, a bit more abstraction and you could get to define a view, mark it up with some useful attribute and just get you main form to kick off a process which would "just do it".

How to improve the loading time of winform?

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.

WPF InitializeComponent performance problems

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.

Categories

Resources