views:

138

answers:

3

Hello there,

So my question is how to implement cancel/interrupt feature into all (I mean ALL) thread workers in your application in best and most elegant way?

It's not important if it's an HttpWebRequest, IO operation or calculation. User should have an possibility to cancel every action/thread at any moment.

+5  A: 

Use .NET 4.0 Tasks with CancellationTokens - they are the new universal cancellation system.

Stephen Cleary
I agree with Stephen's answer as far as the method of notification. As for how to actually handle the cancellation, that would need to be determined separately for each asynchronous task, as different processes will have different points at which they can be safely canceled, may require rollback if changes are not complete, etc. Not all preexisting asynchronous calls even support cancellation.
Dan Bryant
Good point, Dan. Most asynchronous calls do support different types of cancellation, but some do not. Worst-case scenario is to have notification "orphan" the operation if it can't be cancelled, so it will eventually complete in the background, discarding the results.
Stephen Cleary
+5  A: 

User should have an possibility to cancel every action/thread at any moment.

Threading is a practice, not a design... and believe me it has been tried as a design, but it failed miserably. The basic problem with simply canceling any action at any moment is that in a multithreaded environment it's just evil! Imagine that you have a section of code guarded by a lock and you have two threads running in parallel:

  1. Thread 1 acquires the lock.
  2. Thread 2 waits until the lock is released so it can acquire it.
  3. Thread 1 is canceled while it's holding the lock and it doesn't release the lock.
  4. DEADLOCK: Thread 2 is waiting for the lock which will never be released.

This is the simplest example and technically we can take care of this situation in the design, i.e. automatically release any locks that the thread has acquired, but instead of locks think of object states, resource utilization, client dependencies, etc. If your thread is modifying a big object and it's canceled in the middle of the modification, then the state of the object may be inconsistent, the resource which you're utilizing might get hung up, the client depending on that thread might crash... there is a slew of things which can happen and there is simply no way to design for them. In this case you make it a practice to manage the threads: you ensure a safe cancellation of your threads.

Others have already mentioned various methods for starting threads that can be canceled, but I just wanted to touch on the principles. Even in the cases where there is a way to cancel your threads, you still have to keep in mind that you're responsible for determining the safest way to cancel your thread.

It's not important if it's an HttpWebRequest, IO operation or calculation.

I hope now you understand why it's the MOST important thing! Unless you specifically know what your thread is doing, then there is no safe way to automatically cancel it.

P.S.
One thing to remember is that if you don't want hanging threads then for each one of them you can set the Thread.IsBackground flag to true and they will automatically be closed when your application exits.

Lirik
A: 

Your worker threads need a way to check with your main thread to see if they should keep going. One way is to share a static volatile bool that's set by your UI and periodically checked by the worker threads.

My preference is to create your own threads that run instances of a worker class that periodically invoke a callback method provided by your main thread. This callback returns a value that tells the worker to continue, pause, or stop.

Avoid the temptation to use Thread.Abort() to kill worker threads: http://stackoverflow.com/questions/771134/manipulating-a-thread-from-a-different-thread.

ebpower