This is an adaptation of the code from the MSDN help file. I prefer it to calling Thread.Abort() as a first chance approach for terminating a thread.
A word of caution: It looks as though the ThreadAbortException skips over any finalization code that might occur inside of the executing thread. For example, the background threaded code was using an IDisposable resource (like a reader/writer), I don't believe the finalizer gets called on the resource, leaving it open.
In my example, I've added a flag accessible to the worker thread to indicate my intent to terminate itself. The worker thread periodically polls its value to see if it should die. I've implemented the Thread.Abort() approach as a backup in case the thread takes too long to poll for its TerminateThread value.
using System;
using System.Threading;
public class ThreadWork
{
public static bool TerminateThread;
public static void DoWork()
{
try
{
for (int i = 0; i < 100; i++)
{
if (TerminateThread)
{
Console.WriteLine("Thread exiting at your request.");
break;
}
Console.WriteLine("Thread - working.");
Thread.Sleep(100);
}
}
catch (ThreadAbortException e)
{
Console.WriteLine("Thread - caught ThreadAbortException - resetting.");
Console.WriteLine("Exception message: {0}", e.Message);
Thread.ResetAbort();
}
Console.WriteLine("Thread - finished working.");
}
}
class ThreadAbortTest
{
public static void Main()
{
ThreadStart myThreadDelegate = ThreadWork.DoWork;
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
Thread.Sleep(100);
// tell the thread to terminate itself
ThreadWork.TerminateThread = true;
// give the worker thread a chance to poll the value of TerminateThread
Thread.Sleep(120);
if (myThread.IsAlive)
{
Console.WriteLine("Main - aborting my thread.");
//forcibly kill the thread, this will throw a ThreadAbortException in the worker thread
myThread.Abort();
// wait for the thread to end
myThread.Join();
}
Console.WriteLine("Main ending.");
Console.ReadLine();
}
}