Вопрос по c#, multithreading – Уничтожение потока .NET

19

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

Как уже говорили другие, делайте все возможное, чтобы никогда не делать этого; Вы должны пытаться никогда не создавать поток, который делает то, что вы не можете контролировать. Если вам нужно уничтожить работающий код, который вы не можете контролировать, самое безопасное, что нужно сделать, это запустить код в другом ПРОЦЕССЕ, а не в другой НИТЕ. Намного безопаснее снять процесс, чем поток. Eric Lippert
Вы читали "примечание"? раздел на MSDN? НИКОГДА НЕ ИСПОЛЬЗУЙТЕ АБОРТ. ОНА ПРЕДНАЗНАЧЕНА КАК ПОСЛЕДНИЙ КУРОРТ. ЕСЛИ ВЫ ИСПОЛЬЗУЕТЕ THREAD.ABORT, НЕБО МОЖЕТ БЫТЬ ВНИЗ И КОТЕНО БУДЕТ УБИТ. J-16 SDiZ
Котик? Я думал, что это курица :) Но ваш аватар объясняет ваш комментарий! Rashmi Pandit

Ваш Ответ

7   ответов
2

volatile bool shutdown = false;

void RunThread()
{

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

void StopThread()
{
   shutdown = true;
}
2

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

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

9

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

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

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

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

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

Error: User Rate Limit Exceededwhile (!WillTerminate) {..} HasTerminate.Set();
Error: User Rate Limit ExceededBackgroundWorkerError: User Rate Limit ExceededDoWorkError: User Rate Limit Exceeded
48
Do not call Thread.Abort()!

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

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

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededselect()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
7

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

Use Thread.Interrupt to poke it if it is blocked. Poll a flag variable. Use the WaitHandle class to send a signal.

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
25

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

volatile bool shutdown = false;

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

void StopThread()
{
   shutdown = true;
}

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

1

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

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

Проверьте это на примерах!

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