namespace ElegantThreadWork
using System.Diagnostics;
public CancellationToken CancellationToken { get; private set; }
public ManualResetEvent WaitHandle { get; private set; }
public ThreadObject(CancellationToken ct, ManualResetEvent wh)
static void DoWork(CancellationToken ct)
Console.WriteLine("Thread[{0}] started", Thread.CurrentThread.ManagedThreadId);
while(!ct.IsCancellationRequested)
Console.WriteLine("Thread[{0}]: {1}", Thread.CurrentThread.ManagedThreadId, i);
ct.WaitHandle.WaitOne(TimeSpan.FromSeconds(1));
Console.WriteLine("Thread[{0}] has been cancelled", Thread.CurrentThread.ManagedThreadId);
static void ThreadProc(object state)
ThreadObject to = (ThreadObject)state;
DoWork(to.CancellationToken);
public static void Main(string[] args)
TimeSpan MAX_THREAD_EXITING_TIMEOUT = TimeSpan.FromSeconds(5);
ManualResetEvent isThreadExitedEvent = new ManualResetEvent(false);
CancellationTokenSource cts = new CancellationTokenSource();
ThreadObject threadObj = new ThreadObject(cts.Token, isThreadExitedEvent);
Thread thread = new Thread(ThreadProc, 0);
Console.WriteLine("Just do something in main thread");
Console.WriteLine("Bla.");
Console.WriteLine("Bla..");
Console.WriteLine("Bla...");
Console.WriteLine("Thread cancelattion...");
Stopwatch sw = Stopwatch.StartNew();
var isOk = isThreadExitedEvent.WaitOne(MAX_THREAD_EXITING_TIMEOUT);
Console.WriteLine("Waiting {0} for thread exiting. Wait result: {1}. Cancelled in {2}", MAX_THREAD_EXITING_TIMEOUT, isOk, sw.Elapsed);