Question

I'm writing a WinForms window in C# which displays about 12 ListBox and 6 ComboBox controls each with a few hundred to a few thousand items.

It takes a little while to populate these. Not a long while - just a few seconds, but it's nice for the user to have something to look at so they know the program is working away in the background while they wait.

I have a generic "Please Wait" animated borderless top-most window which appears while this happens, however I'm having trouble with the animation.

For most tasks which take a little while, I solve this in the following way:

Program.ShowPleaseWait(); // Show top-most animation

Thread t = new Thread(stuffToDo); // Run stuffToDo() in separate thread
t.Start();

While (t.IsAlive)
  Application.DoEvents(); // Run message queue, necessary for animation

Program.HidePleaseWait(); // Hide top-most animation

and it works quite well. Occasionally the stuff in the thread will need to Invoke something and that sometimes causes a small hiccup in the animation, but it's generally not a big deal.

With this form, however, the entire code in the thread is UI code: populating ListBoxes and ComboBoxes. That means everything would have to be enclosed with Invoke blocks, which doesn't make any sense because then there's no point in having it run in a separate thread in the first place.

Aside from scrapping the whole worker thread for this particular case and throwing in an Application.DoEvents() every hundred or so insertions in each loop, is there anything I can do to allow the working animation to continue while the controls are populated?

Was it helpful?

Solution

Just run your animation in a second thread. You're allowed to have multiple UI threads, what's not allowed is accessing any UI object from a thread other than the one that initialized it. The new thread should accept an instance of LoadingAnimationForm (or whatever you call your animated dialog) and call Application.Run(animForm); When the main thread gets done populating everything, call animForm.Invoke(animForm.Close). Do not call any other methods on animForm from the main thread.

OTHER TIPS

One possible approach is to use idle time processing for performing your populating code. So you create a dialog box class that is used to show yours waiting animation. You hook into the idle time processing event at the same time you show the waiting dialog box. Once the idle time processing has fully completed you send a message to your dialog telling it to quit.

The only complication is you need to organize your idle time event so it only performs a little work each time it is called, rather than performing all of it in one go. If you perform it all in one go then the dialog never has chance to process and show an updated wait animation.

Taken from this post:

May I add this CodeProject link?

All you need is to build, drag from toolbar and use. The LoadingCircle component works without any trouble at all. Works like a charm, you can even customize it!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top