using System; using System.ComponentModel; namespace ConsoleApplication6 { class Program { static bool ThreadCancelled = false; static SomethingTheWorkerBuilds theResult; static void Main(string[] args) { BackgroundWorker bg = new BackgroundWorker(); bg.WorkerSupportsCancellation = true; bg.WorkerReportsProgress = true; bg.DoWork += new DoWorkEventHandler(bg_Work); bg.ProgressChanged += new ProgressChangedEventHandler(bg_ProgressChanged); bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted); bg.RunWorkerAsync(); System.Threading.Thread.Sleep(5000); //Cancel the thread: //bg.CancelAsync(); DoSomethingThatRequiresThreadCompleted(); Console.ReadLine(); } static void bg_ProgressChanged(object sender, ProgressChangedEventArgs e) { Console.WriteLine("Progress {0}", e.ProgressPercentage); } static void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) ThreadCancelled = true; else theResult = (SomethingTheWorkerBuilds)e.Result; } static void bg_Work(object sender, DoWorkEventArgs e) { BackgroundWorker bg = sender as BackgroundWorker; for (int i = 0; i < 10; i++) { if (bg.CancellationPending) { e.Cancel = true; break; } System.Threading.Thread.Sleep(1000); bg.ReportProgress(i); } e.Result = new SomethingTheWorkerBuilds(); } static void DoSomethingThatRequiresThreadCompleted() { Console.WriteLine("Waiting for thread"); while (theResult==null && !ThreadCancelled) { } if (ThreadCancelled) Console.WriteLine("Thread cancelled"); else //Carry on Console.WriteLine(theResult.Text); } } class SomethingTheWorkerBuilds { public string Text = "Hello World"; } }(ISTR I couldn't trust using BackgroundWorker.IsBusy because that would return false before 'theResult' was populated - but I might be wrong)