views:

102

answers:

2

I'm creating a custom charting control and I would like to have the possibility of displaying some sort of wait bar while other commands are running (i.e. chart is being created).

I'm using ProgressBar (System.Windows.Forms.ProgressBar in marquee mode) as a part of this control. I do not need to update the state of the progress bar, I just want it to move over and over until the chart is created.

Right now I'm using it in following scheme:
- Start wait bar (ProgressBar appears and starts running)
- Call charting methods
- When the chart is ready, the wait bar will being hidden.

The problem is: Some charting methods are really computational demanding and the wait bar freezes in such moments. How can I avoid these freezes? Should I use some kind of threading/background worker? And if yes, then what is the simplest way to do it?

Note, that I do not need to change the state of the progress bar while the chart is being prepared. I just need the wait bar to start, run during all computations and stop after that.

EDIT

OK, as suggested, I created a separate thread for these demanding computations to avoid freezes.

But how to wait for a thread to finish and do not freeze the GUI?

I tried, as suggested here, something like that:

Thread t = new Thread( () => { DoSomeLongAndDemandingTask(withParameters); });
t.Start();
t.Join()

// do something that needs to be done after thread finishes
InvokeMeAfterThreadFinished();

But it freezes the GUI. Is there any other way to avoid these freezes?

+4  A: 

You've answered your own question - typically the answer is to move the computation onto a background thread. There is a WinForms component called the BackgroundWorker, does a lot of the lifting for you:

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx http://dotnetperls.com/backgroundworker

Note that you won't be able to access UI components from the background thread, you need to Control.Invoke onto the UI thread to get access to UI controls. This is heavily talked about (and solutions provided) on the net so Googling will be easy for this.

Alternatively, sometimes a background thread is unworkable (not sure why), so you can use Application.DoEvents() - if memory serves, this processes pending messages on the message queue (including control painting, UI updating). If you only do a little work that causes jittering, this could be a faster and simpler option - though not advised too often.

Adam
Is there any way of running ProgressBar in a BacgroungWOrker, instead of charting methods?
Gacek
Not on the same form I don't think, but there is nothing stopping you from showing a form on another thread by using another `Application.Run(new ProgressForm())` - usually done the other way round though.
Adam
+1  A: 

Using the BackgroundWorker class is the simplest way to perform a background computation.

However, just be careful that the charting methods you are running in the background do not update the UI. All updates to the UI itself must be performed by the UI thread. So a background thread will need to "marshall" such calls to the UI - see Control.Invoke for a starting point on that.

Justin Ethier