如何正确停止正在使用Control.Invoke的线程

3
我尝试了以下伪代码,但当我尝试停止线程时,总是会发生死锁。 问题在于Join()等待线程完成,而挂起的Invoke()操作也正在等待完成。我该如何解决?
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();
}
3个回答

4
你可以使用BeginInvoke(ReportProgress) - 这样你的工作线程就不必等待UpdateStatusBarAndStuff方法完成。

1

请使用 `BeginInvoke' 代替


0

我会用稍微不同的方法来做:

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();
}

最佳实践建议是“不要中止”。这是基于一个事实,即您不知道中止调用将在代码的哪一点退出 - 它可能会在创建Stream的过程中中止。因此,你面临一个选择:你能保证无论代码在哪一行退出,它都会处于一个合理的状态吗?
如果不能保证,那么你就需要使用Thread.Join()
即使使用了Thread.Join,用户可能会厌烦并退出(ALT + F4)应用程序,这将导致与Thread.Abort()调用时相同的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接