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

1 ответ:

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

Как намекает Ганс, ICLRPolicyManager хозяина используется для определения того, какие исключения являются фатальными при выполнении кода на конкретном хосте (особенно SQL Server). Смотрите красивую сетку внизу этой страницы документации: ICLRPolicyManager:: SetActionOnFailure Method