Методы Interrupt и Abort - подробное разъяснение

Методы Interrupt и Abort - подробное разъяснение

Методы Interrupt и Abort действуют вытесняющим образом на другой поток.

Метод Interrupt не имеет допустимых сценариев использования, тогда как метод Abort изредка полезен. Метод Interrupt принудительно освобождает заблокированный поток, генерируя на нем исключение ThreadlnterruptedException. Если поток не блокирован, выполнение продолжается до его следующего блокирования, после чего генерируется исключение ThreadlnterruptedException. Метод Interrupt бесполезен, поскольку отсутствуют сценарии, для которых нельзя было бы построить лучшее решение с помощью сигнализирующих конструкций и признаков отмены (или метода Abort). Он также по своей сути опасен, т.к. никогда нельзя иметь уверенность, в каком месте кода поток окажется принудительно деблокированным (это может произойти внутри кода самой платформы .NET Framework, например).

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



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

Для предохранения целостности домен приложений учитывает любые блоки finally, а статические конструкторы никогда не прекращаются на середине своего выполнения. С учетом этого, метод Abort не подходит для реализации универсальной отмены, поскольку существует возможность, что прекращенный поток вызовет проблемы и нарушит работу домена приложения (или даже процесса). Например, предположим, что конструктор экземпляров типа получает неуправляемый ресурс (скажем, файловый дескриптор), который освобождается в методе Dispose типа.

Если поток прекращается до полного завершения конструктора, частично сконструированный объект не сможет быть освобожден и произойдет утечка неуправляемого дескриптора. (Финализатор, если присутствует, по-прежнему запустится, но только чтобы сборщик мусора смог обработать объект.) Эта уязвимость характерна для базовых типов .NET Framework, включая FileStream, и делает метод Abort неподходящим в большинстве сценариев.

Если альтернатива использованию метода Abort отсутствует, то смягчить большую часть потенциальных разрушений можно за счет запуска потока в другом домене приложения и воссоздании текущего домена после прекращения потока (именно так поступает средство LINQPad, когда вы отменяете запрос).

Вполне допустимо и безопасно вызывать метод Abort на собственном потоке, поскольку вам точно известно, что в нем происходит. Иногда это удобно в ситуации, при которой требуется, чтобы исключение генерировалось повторно после каждого блока catch — как раз это и делает инфраструктура ASP.NET, когда вы вызываете метод Redirect.


Другие материалы по теме:
Что вы об этом думаете?
ВКонтакте
Смотрите также:

Главные новости

Новости партнеров