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
ExecuteCodeWithGuaranteedCleanup
correctly? - When is
ExecuteCodeWithGuaranteedCleanup
actually 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
精彩评论