I'm also regularly using an EventWaitHandle (ManualResetEvent/AutoResetEvent) in combinition with the following snipet:
WaitHandle[] handles = new WaitHandle[] { exitEvent, null };
while(!exitEvent.WaitOne(0, false))
{
IAsyncResult result = something.BeginSomeMethod(null, null);
handles[1] = result.AsyncWaitHandle;
if(WaitHandle.WaitAny(handles) == 0)
{
break;
}
something.EndSomeMethod(result);
}
I coded this just from memory so no garanty of correct syntax!
To exit the thread I use exitEvent.Set() on any thread which wants to stop the thread. This call is often followed by a thread.Join();
Well the question was how to stop a thread, the above code looks more like waiting for thread completion.
Ian wrote a post about killing threads over here: http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
Async operations like Beginxxxx or jobs quedued to the threadpool is not possible to cancel.
I disagree with the opportunity of Thread.Abort().
Worst case (maybe average case): you're in the middle of a locked region. You know that some state is not valid all the time, that's why you're synchronizing with a lock (e.g. two sequencial changes of different values). Now if you've changed the first value and a ThreadAbortException occures, your lock will be released (because of the finally block) without changing the second value and so your code is in an invalid state which may (and most of the time will) cause a malfunction of your other threads and maybe your whole application. That's why you should never use Thread.Abort, Thread.Suspend or Thread.Resume and that's also why the framework-designers consider to remove this methods in future releases. The only legitim call to them is at app-shutdown and that's where they are called by the CLR, but your own code should never use them.
Use the way I described in a previous post: set events or values which are checked at places where your code is in a valid state to exit and simply return there from your threaded method!
Lowendahl wrote:
Well the question was how to stop a thread, the above code looks more like waiting for thread completion.
Ian wrote a post about killing threads over here: http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
Async operations like Beginxxxx or jobs quedued to the threadpool is not possible to cancel.
Of course, my "something" gets invalid after the exit of the thread and should not be used anymore, but there is no way to abort blocking operations (Abortxxx would be nice to be added to the async pattern). But I prefer my code and the penalty of "loosing" the object on which I'm performing the blocking operations over thread.Abort() where I loose everything which may be left in an invalid state by the thread (including my "something").