Аварийное завершение потоков

Поток может быть аварийно завершен при помощи метода Abort:

class Abort { static void Main() { Thread t = new Thread(delegate() { while (true); }); // Бесконечный цикл t.Start(); Thread.Sleep(1000); // Пусть поработает секунду... t.Abort(); // после чего принудительно завершим его. } }

Аварийно завершаемый поток немедленно переходит в состояние AbortRequested. Если завершение проходит как ожидалось, поток переходит в состояние Stopped. Поток, вызвавший Abort, может ожидать этого, вызвав Join:

class Abort { static void Main() { Thread t = new Thread(delegate() { while (true); }); // Бесконечный цикл Console.WriteLine(t.ThreadState); // Unstarted t.Start(); Thread.Sleep(1000); Console.WriteLine(t.ThreadState); // Running t.Abort(); Console.WriteLine(t.ThreadState); // AbortRequested t.Join(); Console.WriteLine(t.ThreadState); // Stopped } }

Вызов Abort вызывает генерацию исключения ThreadAbortException в завершаемом потоке, в большинстве случаев прямо там, где поток находится в это время. Завершаемый поток может обработать это исключение, но оно будет автоматически выброшено снова в конце блока catch (чтобы содействовать завершению потока, как это и предполагалось). Можно, однако, предотвратить автоматический повторный выброс исключения с помощью вызова Thread.ResetAbort в блоке catch. В этом случае поток возвращается в состояние Running (из которого его можно опять попытаться принудительно прекратить). В следующем примере рабочий поток воскресает из мертвых всякий раз после вызова Abort:

class Terminator { static void Main() { Thread t = new Thread(Work); t.Start(); Thread.Sleep(1000); t.Abort(); Thread.Sleep(1000); t.Abort(); Thread.Sleep(1000); t.Abort(); } static void Work() { while (true) { try { while (true) ; } catch(ThreadAbortException) { Thread.ResetAbort(); } Console.WriteLine("Я не умру!"); } } }

Необработанное ThreadAbortException, однако, не приводит к аварийному завершению приложения, в отличие от других типов исключений.

Abort будет воздействовать на поток в любом состоянии – рабочем, заблокированном, приостановленном или остановленном. Если, однако, принудительно завершается приостановленный поток, генерируется ThreadStateException – на сей раз в вызывающем потоке – и принудительное завершение не может быть произведено, пока поток не возобновит работу. Вот как можно принудительно завершить приостановленый поток:

try { suspendedThread.Abort(); } catch(ThreadStateException) { suspendedThread.Resume(); } // Сейчас suspendedThread будет принудительно прекращен.

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: