我一直在阅读Reliability Features in .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
何时实际有用?答案 0 :(得分:4)
某些异常对于进程是致命的,并且用户提供的代码的执行不会继续。 ExecuteCodeWithGuaranteedCleanup
方法的目的是让您可以将数据结构恢复到一致状态。如果这个过程无论如何都会无法阻止它,那么这没有任何意义。操作系统(假设它正常工作)将在进程结束时自动为您清理任何内核对象,无论进程何时结束。
正如Hans所暗示的那样,当代码在特定主机(尤其是SQL Server)中运行时,主机的ICLRPolicyManager
会发挥作用来确定哪种异常是致命的。请参阅本文档页面底部的漂亮网格:ICLRPolicyManager::SetActionOnFailure Method