Подтвердить что ты не робот

Убийство потока .NET

Я создал поток, выполняющий определенный метод. Но иногда я хотел бы убить поток, даже если он все еще работает. Как я могу это сделать? Я попробовал Thread.Abort(), но он обнаружил сообщение с сообщением "Thread aborted". Что мне делать?

4b9b3361

Ответ 1

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

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

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

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

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}

Ответ 2

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

volatile bool shutdown = false;

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

void StopThread()
{
   shutdown = true;
}

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

Ответ 3

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

В вашей теме вы можете:

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

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

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

Ответ 4

Не рекомендуется убивать поток. Лучше сказать, что он должен остановиться и позволить ему закончить изящно. Существуют различные способы сделать это.

  • Используйте Thread.Interrupt, чтобы вытолкнуть его, если он заблокирован.
  • Опросите переменную флага.
  • Используйте класс WaitHandle для отправки сигнала.

Мне не нужно перефразировать, как каждый метод можно использовать, поскольку я уже сделал это в этом ответе.

Ответ 5

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

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

Ответ 6

Я согласен с Джоном Б

volatile bool shutdown = false;

void RunThread()
{

try
{
    while (!shutdown)
    {
        /* Do work. */
    }
}
catch (ThreadAbortException exception)
{
    /* Clean up. */
}
}

void StopThread()
{
   shutdown = true;
}

Ответ 7

Также есть примеры уничтожения потоков в моем классе WebServer...

https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948

Я бы сказал, что Abort в порядке, просто понять, что такое разветвления... пока вы указываете состояние перед долгой работой Abort будет работать, но нужны флаги, такие как (ShouldStop или ActionBranch и т.д.)

Ознакомьтесь с примерами!