tags:

views:

218

answers:

4

besides updating GUI controls from background threads, is there any other operations that should avoid being done on background threads in winforms?

+2  A: 

This is sort of broad. Don't do anything in a background thread if you don't need to; that is, don't thread out some code just because you feel like it. Use threads where it is appropriate such as for long running tasks that you do not want to interrupt the GUI and so forth. Also, if you end up just calling Application.DoEvents() from your main UI thread just waiting on a task from another thread, you might think about keeping one thread and doing the work in small pieces in a loop where you would repaint the GUI with DoEvents() calls. This is just a suggesiton; however, of course, many times you do need to create multiple threads.

Perhaps you can ask about particular situations?

BobbyShaftoe
A: 

I agree with Bobby that your question is too broad. Instead start with the assumption that if you have to create a worker thread, you're not going to put anything in it except what absolutely has to be there to complete the required task.

Jim H.
+1  A: 

Well, the reason you should not update GUI controls on a background thread is that the GUI control classes are not threadsafe. So, you can generalize that: don't mess with instances of non-threadsafe classes from a background thread if there is some other thread that might also use them. (That's broad, I know, but anything that breaks that rule could get you in trouble).

But I think the gist of your question is whether or not you've covered all the bases that Control.Invoke() was created to cover. If so, yes, you have ... Control.Invoke was specifically designed for the fact that controls are not threadsafe, and therefore, other threads should only modify controls via Control.Invoke().

Charlie Flowers
+3  A: 

Oh, there are plenty of traps. BGW doesn't do much to protect you from the usual hazards of threaded programming. And adds some of its own:

  • Variables that are accessed from both the BGW and the UI thread must be protected by a lock.
  • Do not update a bound data source in a BGW. The control updates will be done on the BGW thread but will not generate an exception.
  • Don't call ReportProgress() too often. Doing it more than about 1000 times per second will freeze the UI thread. About 25 times/sec is enough.
  • Careful with the userstate argument you can pass to ReportProgress(). It must not be modified by the BGW after the call.
  • Don't loop on the IsBusy property in the UI thread, it will deadlock.
  • The BGW thread will be aborted when the main form closes. Watch out for necessary cleanup.
  • Be sure to inspect the Error property in the RunWorkerCompleted event, it tells you when something went wrong.
Hans Passant
That's a good answer. +1
Charlie Flowers