How to correctly stop thread which is using Control.Invoke
I tried the following (pseudocode) but I always get a deadlock when Iam tryin开发者_Python百科g to stop my thread. The problem is that Join() waits for the thread to complete and a pending Invoke() operation is also waiting to complete. How can I solve this?
Thread workerThread = new Thread(BackupThreadRunner);
volatile bool cancel;
// this is the thread worker routine
void BackupThreadRunner()
{
while (!cancel)
{
DoStuff();
ReportProgress();
}
}
// main thread
void ReportProgress()
{
if (InvokeRequired)
{
Invoke(ReportProgress);
}
UpdateStatusBarAndStuff();
}
// main thread
void DoCancel()
{
cancel=true;
workerThread.Join();
}
You could use BeginInvoke(ReportProgress)
- that way your worker thread doesn't have to wait for the UpdateStatusBarAndStuff
method to finish.
use `BeginInvoke' instead
I would do it a slightly different way:
private Thread workerThread;
void StartButtonClick()
{
workerThread = new Thread(ReportProgress);
thread.Start();
}
void CancelButtonClick()
{
// If you use a while(bool), it will repeat the task forever
// or with no while and just a bool, you'll have to check the value of the bool in each line
// so simply aborting it (providing you clean up) is accceptable.
workerThread.Abort();
// If you don't mind your user waiting:
// workerThread.Join(1000);
}
void ReportProgress()
{
if (InvokeRequired)
{
Invoke(ReportProgress);
return;
}
UpdateStatusBarAndStuff();
}
The best practice advice is "don't abort". This is based on the fact you don't know at what point the abort call will exit your code - it could be half way through creating a Stream
. So you end up with a choice: can you guarantee that at whatever line the code exits, it will be in a reasonable state to do so?
If you can't then you will need to use a Thread.Join()
.
Even with a Thread.Join
, the user may get bored and quit (ALT+F4) the app, and you have exactly the same situation as you had with the Thread.Abort()
call.
精彩评论