private ManualResetEvent m_Event = new ManualResetEvent (); private event EventHandler ThreadComplete; public void StartThread() { ThreadComplete += new EventHandler (HandleOnThreadComplete); ThreadPool.QueueUserWorkItem (new WaitCallback (ThreadRun), ar); } private void ThreadRun () { while(true) { // do work, do work if(m_Event.WaitOne(0)) { // time to exit OnThreadComplete (); return; } } } private void OnThreadComplete() { if(ThreadComplete != null) { ThreadComplete (this, new EventArgs ()); } } private void OnButtonClick() { m_Event.Set (); // Tell the thread it's time to exit gracefully; } void HandleOnThreadComplete (object sender, EventArgs e) { this.Invoke (new MethodInvoker (delegate { MyWaitDialog.Close (); } )); }