Уничтожение потока.NET

Разработчики должны иметь возможность изменять производственный код без получения разрешения от кого-либо, если они документируют свои изменения и уведомляют соответствующие стороны.

19
задан John Saunders 10 March 2015 в 04:30
поделиться

4 ответа

Не вызывайте Thread.Abort () !

Thread.Abort опасно. Вместо этого вы должны сотрудничать с потоком, чтобы его можно было спокойно закрыть. Поток должен быть спроектирован так, чтобы ему можно было приказать убить себя, например, с помощью логического флага keepGoing , который вы устанавливаете в false, когда хотите, чтобы поток остановился. Тогда поток будет иметь что-то вроде

while (keepGoing)
{
    /* Do work. */
}

. Если поток может заблокироваться в режиме Sleep или Wait , вы можете вывести его из этих функций, вызвав Thread.Interrupt ( ) . Затем поток должен быть подготовлен к обработке исключения ThreadInterruptedException :

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}
48
ответ дан 30 November 2019 в 01:48
поделиться

Вы действительно должны вызывать Abort () только в крайнем случае. Вместо этого вы можете использовать переменную для синхронизации этого потока:

volatile bool shutdown = false;

void RunThread()
{
   while (!shutdown)
   {
      ...
   }
}

void StopThread()
{
   shutdown = true;
}

Это позволяет вашему потоку полностью завершить то, что он делал, оставляя ваше приложение в заведомо исправном состоянии.

26
ответ дан 30 November 2019 в 01:48
поделиться

Прерывание потока - очень плохая идея, поскольку вы не можете определить, что поток делал во время прерывания.

Вместо этого имейте свойство, которое поток может проверить, и что ваш внешний код может установить. Позвольте потоку проверять это логическое свойство, когда он находится в безопасном месте для выхода.

2
ответ дан 30 November 2019 в 01:48
поделиться

Самый правильный и Поточно-ориентированный способ - использовать WaitHandle, чтобы сообщить потоку, когда он должен остановиться. Я в основном использую ManualResetEvent.

В вашем потоке вы можете иметь:

private void RunThread()
{
    while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
    {
        // ...
    }
}

где this.flag - это экземпляр ManualResetEvent. Это означает, что вы можете вызвать this.flag.Set () извне потока, чтобы остановить цикл.

Метод WaitOne вернет истину, только если установлен флаг. В противном случае он истечет по истечении заданного времени ожидания (100 мс в примере), и поток снова выполнит цикл.

9
ответ дан 30 November 2019 в 01:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: