Когда 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