Как правильно остановить поток, который использует Control.Invoke - PullRequest
3 голосов
/ 28 мая 2010

Я попробовал следующее (псевдокод), но я всегда захожу в тупик, когда 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 ]

4 голосов
/ 28 мая 2010

Вы можете использовать BeginInvoke(ReportProgress) - таким образом, ваш рабочий поток не должен ждать завершения метода UpdateStatusBarAndStuff.

1 голос
/ 28 мая 2010

используйте взамен `BeginInvoke '

0 голосов
/ 28 мая 2010

Я бы сделал это немного по-другому:

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().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...