views:

463

answers:

4

I have been trying to get a progressbar set to marquee to keep moving while another function is running. After this function runs, I message would display (for this example)

The only way I was able to get this working was with a background worker and then have a

Do Loop until condition that runs in the main form until the operation is complete followed by my message box.

This seems like a kludge way to accomplish this and a thread.start followed by a thread.join seems like a much nicer way to fix this. However, I was not able to get that working either.

I have included a small demo program if anyone is interested. http://www.filedropper.com/progressbar

Thanks

+1  A: 

Use Application.DoEvents() in your function from time to time so that your process has some time to process his events, including redrawing the form.

Alternatively, you can use a worker thread (like a BackgroundWorker) to process your treatement, while the UI thread is displaying your progress bar.

Brann
I have that in my do, loop already. I was thinking I might need to use a delagate and invoke the method. See my example
+6  A: 

Thread.Start and Thread.Join is not the way to do it - that basically blocks your UI thread again. Application.DoEvents isn't the way to go either - you really do want a separate thread.

You could then use Control.Invoke/Control.BeginInvoke to marshal back to the UI thread, but BackgroundWorker makes all this a lot easier. A search for "BackgroundWorker tutorial" yields lots of hits.

EDIT: To show the message when the worker has finished, use the RunWorkerCompleted event. The ReportProgress method and ProgressChanged event are used to handle updating the progress bar. (The UI subscribes to ProgressChanged, and the task calls ReportProgress periodically.)

Jon Skeet
I am currently using background worker, but having to wait for the background worker process to complete by using a do application.doevents loop until seems wrong
Why would you have to wait for the process to complete? You want your UI thread to be free to respond to events (e.g. your window being redrawn).
Jon Skeet
Jon, the 'waiting for the task to complete' often *is* an issue - we're all agreed you can't block the message-pumping thread, but often there's a higher-level application requirement to not allow some other operation to start until this one's finished. Modal progress dialogs rule, perhaps...
Will Dean
@Will: Yes, my comment was written in haste. I guess it should really have been: "I think you've missed the RunWorkerCompleted event" :)
Jon Skeet
I ended up using the RunWorkerCompleted. I will have to do some major redesign for a couple of functions. But I believe it looks a lot better than the do loop stuff and I will be able to sleep better at night. Just wish I could create my own background thread and just do a thread.join.
If doing a Thread.Join was okay, you wouldn't have needed the new thread in the first place :)
Jon Skeet
+3  A: 

That is not a kludge. That is the correct way of doing it; what happens with the BackgroundWorker approach? The trick is to use the ReportProgress method to push the change back to the UI (don't update the ProgressBar from the worker).

Marc Gravell
the progresss bar is a marque, and I always thought a background worker was mostly for asyncrones processes. But I need to halt the main program (except for the marque going) until the process finishes. Please see example
+1  A: 

Complementing the answer given by Marc Gravell, the BackbroundWorker has a boolean property WorkerReportsProgress, if it is set to false, when you call ReportProgress, the program will raise an InvalidOperationException

Jhonny D. Cano -Leftware-