Разработчики должны иметь возможность изменять производственный код без получения разрешения от кого-либо, если они документируют свои изменения и уведомляют соответствующие стороны.
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. */
}
Вы действительно должны вызывать Abort () только в крайнем случае. Вместо этого вы можете использовать переменную для синхронизации этого потока:
volatile bool shutdown = false;
void RunThread()
{
while (!shutdown)
{
...
}
}
void StopThread()
{
shutdown = true;
}
Это позволяет вашему потоку полностью завершить то, что он делал, оставляя ваше приложение в заведомо исправном состоянии.
Прерывание потока - очень плохая идея, поскольку вы не можете определить, что поток делал во время прерывания.
Вместо этого имейте свойство, которое поток может проверить, и что ваш внешний код может установить. Позвольте потоку проверять это логическое свойство, когда он находится в безопасном месте для выхода.
Самый правильный и Поточно-ориентированный способ - использовать WaitHandle, чтобы сообщить потоку, когда он должен остановиться. Я в основном использую ManualResetEvent.
В вашем потоке вы можете иметь:
private void RunThread()
{
while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
{
// ...
}
}
где this.flag
- это экземпляр ManualResetEvent. Это означает, что вы можете вызвать this.flag.Set ()
извне потока, чтобы остановить цикл.
Метод WaitOne вернет истину, только если установлен флаг. В противном случае он истечет по истечении заданного времени ожидания (100 мс в примере), и поток снова выполнит цикл.