views:

123

answers:

1

According to Single-Threaded Application with Long-Running Calculation MSDN example, there is a possibility of creating a responsive GUI in just 1 thread. Thanks to the Dispatcher object, as we can set the Priority of work items.

My question is, what sense does it have to do simple tasks (supposing we just have 1 single core cpu) in a background thread when this is possible?

Thanks

+3  A: 

Essentially the example has broken up the single task of 'finding as many prime numbers as you can' into many, many fast running individual steps that are executed at a very low priority, so that they're unlikely to interrupt a user interacting with the window.

One drawback I feel is that it forces the programmer to break up a task into many small steps that we have to guarantee can be executed quickly. When one of those tasks is running, it's blocking the UI for the entire duration of it. Consider downloading a file. Taking the single step of connecting to an FTP site could take 20 seconds or more, during which time the UI is frozen.

Compare this with a proper thread doing the whole download in one go, marshalling updates back to the UI thread. Even on a single core machine this should provide a reasonable user experience.

The next drawback is that you're now executing code on a single thread. This isn't as great as it sounds. Because of the way that the small individual tasks are being queued, other tasks (anything pushed onto the window's message queue) have a chance to jump in and execute in amongst them. If the state that your special tasks use is not properly isolated, you can get issues that look like threading issues but aren't, and worse still, you cannot protect yourself from those issues using locking, as all actions are performed on the same thread. There are similar drawbacks when using Application.DoEvents(), (although there's some extra nasty stuff that can go on with that which can't go on here).

So the technique you outlined may be usable for some situations, and for some maybe not. I'd therefore go for the technique which is always applicable, which is running the code on a background thread.

I think the answer is usually the same for most 'use a single thread whilst keeping the UI responsive questions'. You can't really. You have to bite the bullet and learn to thread properly. Think hard, isolate your state, protect state using immutability and locking, and marshal calls properly betweeen threads where needed.

Alex Humphrey
Thank you for a great response +1
PaN1C_Showt1Me