Howto wait work thread in the main Form?
after reading a few articles, I am still not sure I understand Multi-threading to solve my particular problem.
I have a Main form which will start a background worker thread(worker). The worker thread will d开发者_如何学Coing a While(!Stopping) infinity loop and will sleep at end of each iteration terminate by global Stopping object(Read only lock object). With working fine when user press Stop button, the worker will stop after current iteration.
Now I want when user close the main form, it will set Stop flag first, let the worker thread finish its current job. After that the main form will close. Seems simple enough, but I couldn't make it working.
I tried either worker.Join(), or test woker.IsAlive in a while loop, but both case will lock the application(Main form) after a few seconds for some reason ?
The following is my code inside Form_Closing event handler (not working):
// Tell the thread to stop the file
Stop();
Logger.Info("Stopping the thread by Close the application");
//Not working as well
//worker.Join();
while (worker.IsAlive)
{
Thread.Sleep(5000);
Logger.Info("After sleep for 5 seconds");
}
Logger.Info("worker thread stopped");
One thing interesting is that the worker thread seems always writes log event until the end of each loop iteration, then the rest of the log entry will be main form event inside the while(worker.IsAlive) loop.
Join will always wait on the thread, using it in the UI thread will make application seem to be locked. IsAlive do not block anything in the GUI thread, it's your Thread.Sleep.
do somethnig like this instead:
while (worker.IsAlive)
{
Thread.sleep(50);
Application.DoEvents();
}
You are creating a deadlock somehow put a break point everywhere you request and release the locking object. Also you can use the system.threading.monitor class to test to see if the lock is available rather then creating a deadlock. Get Very familiar with the threads window in VS.
Keep in mind that any code you use that causes the UI thread to suspend its normal obligation of pumping messages will manifest itself as a hang to the user. In other words, do not call any method which may block including Thread.Join
, Thread.Sleep
, WaitHandle.WaitOne
, etc.
Since you want the worker to terminate upon closing the form then I suggest letting the form close after the stop signal has been sent to the worker thread. Add a Thread.Join
call to the entry point of your application after the call to Application.Run
. Since you are shutting down the application it is safe to call Thread.Abort
if the thread does not respond in a timely manner. Here is some example code.
public void Main(string[] args)
{
var form = new YourForm();
Application.Run(form);
if (!form.WorkerThread.Join(TIME_TO_WAIT))
{
form.WorkerThread.Abort();
}
}
精彩评论