В MSDN описание метода Thread.Abort() говорит: "Вызов этого метода обычно завершает поток".
Почему бы не ВСЕГДА?
В каких случаях он не прерывает поток?
Есть ли другая возможность прекратить потоки?
В MSDN описание метода Thread.Abort() говорит: "Вызов этого метода обычно завершает поток".
Почему бы не ВСЕГДА?
В каких случаях он не прерывает поток?
Есть ли другая возможность прекратить потоки?
Thread.Abort()
вводит a ThreadAbortException
в поток. Поток может отменить запрос, вызвав Thread.ResetAbort()
. Кроме того, есть определенные части кода, такие как блок finally
, который будет выполняться до обработки исключения. Если по какой-то причине поток застрял в таком блоке, исключение никогда не будет поднято в потоке.
Поскольку вызывающий абонент имеет очень мало контроля над состоянием потока при вызове Abort()
, обычно это не рекомендуется. Передайте сообщение потоку, запрашивающему завершение.
В каких случаях он не прерывает поток?
Этот вопрос является дубликатом.
Что не так с помощью Thread.Abort()
Есть ли другая возможность прекратить потоки?
Да. Ваша проблема в том, что вы никогда не должны запускать нить, которую вы не можете вежливо сказать, и она останавливается своевременно. Если вы находитесь в ситуации, когда вам нужно запустить поток, который может быть (1) трудно остановить, (2) ошибкой или худшим из всех (3) враждебным для пользователя, тогда правильная вещь - сделать новый процесс, запустите поток в новом процессе, а затем завершите процесс, когда хотите, чтобы поток опустился. Единственное, что может гарантировать безопасное прекращение несовместимого потока, - это операционная система, снимающая весь процесс.
См. мой чрезмерно длинный ответ на этот вопрос для более подробной информации:
Использование оператора блокировки в цикле на С#
Соответствующий бит - это бит в конце, где я обсуждаю, какие соображения касаются того, как долго вы должны ждать, пока нить убьет себя, прежде чем вы его прекратите.
Почему бы не ВСЕГДА? В каких случаях он не конструирует нить?
Для начала поток может перехватить ThreadAbortException
и отменить его собственное завершение. Или он может выполнять вычисления, которые выполняются навсегда, пока вы пытаетесь его прервать. Из-за этого среда выполнения не может гарантировать, что поток будет всегда завершаться после запроса.
ThreadAbortException
имеет больше:
При вызове метода Abort для уничтожения потока общая среда выполнения генерирует исключение ThreadAbortException. ThreadAbortException - особое исключение, которое можно поймать, но оно будет автоматически снова поднято в конце блока catch. Когда это исключение возникает, среда выполнения выполняет все блоки finally до окончания потока. Поскольку поток может выполнить неограниченное вычисление в блоках finally или вызвать
Thread.ResetAbort()
, чтобы отменить прерывание, нет гарантии, что нить никогда не закончится.
Вам не нужно Abort()
поток вручную. CLR сделает для вас всю грязную работу, если вы просто позволите методу в потоке вернуться; который нормально завершает поток.
FileStream.Read()
к именованному каналу, который в настоящее время ничего не получает (считывает блоки вызовов во время ожидания входящих данных) не отвечает на Thread.Abort()
. Он остается внутри вызова Read()
.
Что делать, если поток держит блокировку и прерван/убит? Ресурсы остаются застрявшими
Он отлично работает, когда при вызове потока прервать себя, а не другой нитью. Прерывание, принудительно завершает затронутой нити, даже если она не выполнил свою задачу и не предоставил возможность для очистки ресурсы
ссылка MSDN
см. ниже: Рекомендуемые методы управления потоками
ThreadAborts не будет происходить внутри блока finally или между BeginCriticalRegion и EndCriticalRegion
Потому что вы можете поймать ThreadAbortException
и вызвать Thread.ResetAbort
внутри обработчика.
Я не могу прервать поток, который застревает в цикле:
//immortal
Thread th1 = new Thread(() => { while (true) {}});
Однако я могу прервать поток, если спит во время цикла:
//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
OT: Для всеобъемлющего, языкового агностика, сомнительно полезного и проклятого смешного, возьмите concurrency, см. Verity Stob!
У меня были случаи, когда поток был слишком занят, чтобы услышать вызов Abort(), что обычно приводит к тому, что исключение ThreadAbortingException передается в мой код.