Когда ExecuteCodeWithGuaranteedCleanup фактически гарантирует очистку?
Я читал о функциях надежности в .NET и написал следующий класс для изучения ExecuteCodeWithGuaranteedCleanup
class Failing
{
public void Fail()
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
finally
{
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(Code, Cleanup, "fail");
}
}
private void Code(object message)
{
// Some code in here that will cause an exception...
}
private void Cleanup(object message, bool something)
{
Console.WriteLine(message);
Console.ReadLine();
}
}
Я экспериментировал с различными кодовыми телами для метода Code
. Эти и их результаты выполнения перечислены ниже
Вызывая OutOfMemoryException
- Cleanup
Не называется
List<string> ss = new List<string>();
while (true)
{
string s = new string('x', 1000000);
ss.Add(s);
}
Вызывая StackOverflowException
- Cleanup
Не называется
Code(message); // recursive call
Вызывая ExecutionEngineException
- Cleanup
не делает получить вызов
Environment.FailFast(message.ToString());
Вызывая ThreadAbortException
- Cleanup
вызывается ли (однако регулярное try...finally
также может поймать это исключение)
Thread.CurrentThread.Abort();
Итак, вопросы
- правильно ли я использую
ExecuteCodeWithGuaranteedCleanup
? - Когда
ExecuteCodeWithGuaranteedCleanup
действительно полезно?
1 ответ:
Некоторые исключения фатальны для процесса, и выполнение пользовательского кода просто не продолжается. Цель метода
ExecuteCodeWithGuaranteedCleanup
состоит в том, чтобы вы могли вернуть свои структуры данных в согласованное состояние. Если процесс все равно умрет, и его никак не остановить, то это не имеет никакой цели. ОС (при условии, что она работает правильно) будет автоматически очищать любые объекты ядра, когда процесс завершается, независимо от причины, по которой процесс завершается.Как намекает Ганс,
ICLRPolicyManager
хозяина используется для определения того, какие исключения являются фатальными при выполнении кода на конкретном хосте (особенно SQL Server). Смотрите красивую сетку внизу этой страницы документации: ICLRPolicyManager:: SetActionOnFailure Method