Есть три вида так называемых «асинхронных исключений». Это ThreadAbortException, OutOfMemoryException и упомянутое StackOverflowException. Эти исключения могут возникать при любой инструкции в вашем коде.
И есть способ их преодолеть:
Самый простой - ThreadAbortException. Когда текущий код выполняется в finally-блоке. ThreadAbortExceptions как бы «перемещены» в конец блока finally. Таким образом, все в блоке finally не может быть прервано исключением ThreadAbortException.
Чтобы избежать OutOfMemoryException, у вас есть только одна возможность: ничего не размещать в куче. Это означает, что вам не разрешено создавать какие-либо новые ссылочные типы.
Чтобы преодолеть StackOverflowException, вам понадобится помощь от Framework. Эта помощь проявляется в областях ограниченного выполнения. Требуемый стек выделяется до фактического выполнения кода и дополнительно гарантирует, что код уже JIT-скомпилирован и поэтому доступен для выполнения.
Есть три формы для выполнения кода в ограниченных областях выполнения (скопированы из Блог команды BCL):
- ExecuteCodeWithGuaranteedCleanup, безопасная для переполнения стека форма try / finally.
- Блоку try / finally непосредственно предшествует вызов RuntimeHelpers.PrepareConstrainedRegions. Блок try не ограничен, но есть все блоки catch, finally и fault для этой попытки.
- As a critical finalizer - any subclass of CriticalFinalizerObject has a finalizer that is eagerly prepared before an instance of the object is allocated.
- A special case is SafeHandle's ReleaseHandle method, a virtual method that is eagerly prepared before the subclass is allocated, and called from SafeHandle's critical finalizer.
Вы можете найти больше в этих сообщениях блога:
Ограниченные области выполнения и другие ошибки [Брайан Грюнкемейер] на блог команды BCL.
Журнал Джо Даффи о сбоях атомарности и асинхронных исключений, где он дает очень хороший обзор асинхронных исключений и надежности в .NET Framework.
person
Thomas Danecker
schedule
20.09.2008