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

时间:2010-05-28 08:39:19

标签: c# .net winforms multithreading

我尝试了以下(伪代码),但是当Iam试图阻止我的线程时,我总是陷入僵局。 问题是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 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

使用`BeginInvoke'代替

答案 2 :(得分: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()电话的情况完全相同。