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