С# Thread Termination и Thread.Abort()

В MSDN описание метода Thread.Abort() говорит: "Вызов этого метода обычно завершает поток".

Почему бы не ВСЕГДА?

В каких случаях он не прерывает поток?

Есть ли другая возможность прекратить потоки?

Ответ 1

Thread.Abort() вводит a ThreadAbortException в поток. Поток может отменить запрос, вызвав Thread.ResetAbort(). Кроме того, есть определенные части кода, такие как блок finally, который будет выполняться до обработки исключения. Если по какой-то причине поток застрял в таком блоке, исключение никогда не будет поднято в потоке.

Поскольку вызывающий абонент имеет очень мало контроля над состоянием потока при вызове Abort(), обычно это не рекомендуется. Передайте сообщение потоку, запрашивающему завершение.

Ответ 2

В каких случаях он не прерывает поток?

Этот вопрос является дубликатом.

Что не так с помощью Thread.Abort()

Есть ли другая возможность прекратить потоки?

Да. Ваша проблема в том, что вы никогда не должны запускать нить, которую вы не можете вежливо сказать, и она останавливается своевременно. Если вы находитесь в ситуации, когда вам нужно запустить поток, который может быть (1) трудно остановить, (2) ошибкой или худшим из всех (3) враждебным для пользователя, тогда правильная вещь - сделать новый процесс, запустите поток в новом процессе, а затем завершите процесс, когда хотите, чтобы поток опустился. Единственное, что может гарантировать безопасное прекращение несовместимого потока, - это операционная система, снимающая весь процесс.

См. мой чрезмерно длинный ответ на этот вопрос для более подробной информации:

Использование оператора блокировки в цикле на С#

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

Ответ 3

Почему бы не ВСЕГДА? В каких случаях он не конструирует нить?

Для начала поток может перехватить ThreadAbortException и отменить его собственное завершение. Или он может выполнять вычисления, которые выполняются навсегда, пока вы пытаетесь его прервать. Из-за этого среда выполнения не может гарантировать, что поток будет всегда завершаться после запроса.

ThreadAbortException имеет больше:

При вызове метода Abort для уничтожения потока общая среда выполнения генерирует исключение ThreadAbortException. ThreadAbortException - особое исключение, которое можно поймать, но оно будет автоматически снова поднято в конце блока catch. Когда это исключение возникает, среда выполнения выполняет все блоки finally до окончания потока. Поскольку поток может выполнить неограниченное вычисление в блоках finally или вызвать Thread.ResetAbort(), чтобы отменить прерывание, нет гарантии, что нить никогда не закончится.

Вам не нужно Abort() поток вручную. CLR сделает для вас всю грязную работу, если вы просто позволите методу в потоке вернуться; который нормально завершает поток.

Ответ 4

FileStream.Read() к именованному каналу, который в настоящее время ничего не получает (считывает блоки вызовов во время ожидания входящих данных) не отвечает на Thread.Abort(). Он остается внутри вызова Read().

Ответ 5

Что делать, если поток держит блокировку и прерван/убит? Ресурсы остаются застрявшими

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

ссылка MSDN


см. ниже: Рекомендуемые методы управления потоками

Ответ 7

Потому что вы можете поймать ThreadAbortException и вызвать Thread.ResetAbort внутри обработчика.

Ответ 8

Я не могу прервать поток, который застревает в цикле:

//immortal
Thread th1 = new Thread(() => { while (true) {}});

Однако я могу прервать поток, если спит во время цикла:

//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});

Ответ 9

OT: Для всеобъемлющего, языкового агностика, сомнительно полезного и проклятого смешного, возьмите concurrency, см. Verity Stob!

Ответ 10

У меня были случаи, когда поток был слишком занят, чтобы услышать вызов Abort(), что обычно приводит к тому, что исключение ThreadAbortingException передается в мой код.