разработка надежных хост-приложений
Хост может указать CLR, какие действия следует предпринимать при сбое в управ-
ляемом коде. Вот несколько примеров (от наименее до наиболее серьезного):
1
Конфигурацию класса AppDomainManager можно выполнить также при помощи пере-
менных окружения и параметров реестра, но эти механизмы более громоздки и применять
их имеет смысл разве что в некоторых тестовых сценариях.
632
Глава.22 .Хостинг.CLR.и.домены.приложений
CLR может прервать поток, если тот выполняется слишком долго или долго не
возвращает управление (детали см. в следующем разделе).
CLR может выгрузить домен. При этом закроются все потоки этого домена,
а проблемный код будет выгружен.
CLR может отключиться. При этом прекращается выполнение любого кода
в процессе, но неуправляемому коду работать разрешено.
CLR может выйти из Windows-процесса. При этом сначала закрываются все
потоки и выгружаются все домены — выполняются операции очистки, после
чего процесс закрывается.
CLR может завершить поток или домен как корректно, так и принудительно.
Корректное завершение предусматривает выполнение кода очистки. Иначе говоря,
выполняется код в блоках
finally
и вызываются методы финализации объектов.
При принудительном завершении код очистки игнорируется. При корректном за-
вершении, в отличие от принудительного, не удастся закрыть поток в блоках
catch
и
finally
. Поток, выполняющий неуправляемый код или находящийся в критиче-
ской области (Critical Execution Region, CER), завершить вообще нельзя.
Хост может установить так называемую
политику расширения
(escalation policy),
определив тем самым поведение CLR при сбоях управляемого кода. Например, SQL-
сервер определяет, что должна делать среда CLR при появлении необработанного
исключения во время выполнения управляемого кода. Когда в потоке возникает
необработанное исключение, CLR сначала пытается корректно завершить поток.
Если поток не закрывается за определенное время, CLR пытается перейти от кор-
ректного к принудительному завершению потока.
В большинстве случаев происходит именно так. Однако для потоков из
критиче-
ской области
(critical region) действует другая политика. Поток, находящийся в кри-
тической области, блокируется в рамках синхронизации потоков, причем разбло-
кировать его должен тот же самый поток, например, тот, что вызвал метод
Monitor.
Enter
, метод
WaitOne
типа
Mutex
или один из методов
AcquireReaderLock
или
AcquireWriterLock
типа
ReaderWriterLock
1
. Ожидание методов
AutoResetEvent
,
ManualResetEvent
или
Semaphore
не указывает на пребывание потока в критической
области, потому что другой поток может освободить этот объект синхронизации.
Когда поток находится в критической области, CLR полагает, что он работает
с данными, совместно используемыми несколькими потоками того же домена. Это
и есть наиболее вероятная причина блокирования потока. При работе с общими
данными простое завершение потока является неудачным решением, потому что
к данным могут обращаться другие потоки. Данные же уже повреждены. В итоге
мы получаем непредсказуемое поведение домена и бреши в системе безопасности.
1
При любом блокировании вызываются методы BeginCriticalRegion и EndCriticalRegion
класса Thread, показывающие момент входа в критическую область и выхода из нее. При не-
обходимости вы тоже можете ими воспользоваться. Такая необходимость обычно возникает
при взаимодействии с неуправляемым кодом.
633
Нетривиальное.управление.хостингом
Поэтому, когда в потоке в критической области возникает необработанное
исключение, CLR сначала пытается свести исключение к корректной выгрузке
домена в попытке избавиться от всех используемых потоков и объектов данных.
Если домен не выгружается за указанное время, CLR переходит от корректной
к принудительной выгрузке.
Do'stlaringiz bilan baham: |