When does ExecuteCodeWithGuaranteedCleanup actually guarantee cleanup?
I have been reading about Reliability Features in .NET and have written the following class to explore ExecuteCodeWithGuaranteedCleanup
class Failing
{
    public void Fail()
    {
        RuntimeHelpers.PrepareConstrainedRegions();
        try
        {
        }
        开发者_如何学Cfinally
        {
            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();
    }
}
I have experimented with a variety of code bodies for the Code method. These, and their runtime results are listed below
Causing an OutOfMemoryException - Cleanup does not get called
List<string> ss = new List<string>();
while (true)
{
    string s = new string('x', 1000000);
    ss.Add(s);
}
Causing a StackOverflowException - Cleanup does not get called
Code(message); // recursive call
Causing a ExecutionEngineException - Cleanup does not get called
Environment.FailFast(message.ToString());
Causing a ThreadAbortException - Cleanup does get called (however a regular try...finally can also catch this exception)
Thread.CurrentThread.Abort();
So the questions are
- Am I using ExecuteCodeWithGuaranteedCleanupcorrectly?
- When is ExecuteCodeWithGuaranteedCleanupactually useful?
Some exceptions are fatal to the process and execution of user-supplied code just does not continue. The purpose of ExecuteCodeWithGuaranteedCleanup method is to so you can put your data structures back in a consistent state. If the process is going to die anyways with no way to stop it, this has no purpose. The OS (assuming it is working properly) will clean up any kernel objects automatically for you when a process ends, regardless of the reason the process ends.
As Hans hints, the ICLRPolicyManager of the host comes into play to determine which exceptions are fatal in this way when code is run in a particular host (especially SQL Server). See the nice grid at the bottom of this documentation page: ICLRPolicyManager::SetActionOnFailure Method
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论