我一直在阅读.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();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经为该Code方法试验了各种代码体.下面列出了这些及其运行时结果
导致OutOfMemoryException- Cleanup 不会被召唤
List<string> ss = new List<string>();
while (true)
{
string s = new string('x', 1000000);
ss.Add(s);
}
Run Code Online (Sandbox Code Playgroud)
导致StackOverflowException- Cleanup 不会被召唤
Code(message); // recursive call
Run Code Online (Sandbox Code Playgroud)
导致ExecutionEngineException- Cleanup 不会被召唤
Environment.FailFast(message.ToString());
Run Code Online (Sandbox Code Playgroud)
造成ThreadAbortException- Cleanup 不被调用(但经常try...finally也可以捕获这个异常)
Thread.CurrentThread.Abort();
Run Code Online (Sandbox Code Playgroud)
所以问题是
ExecuteCodeWithGuaranteedCleanup得当吗?ExecuteCodeWithGuaranteedCleanup实际有用?一些异常对进程来说是致命的,用户提供的代码的执行不会继续。ExecuteCodeWithGuaranteedCleanup方法的目的是使您可以将数据结构恢复到一致状态。如果进程无论如何都将终止而无法阻止它,那么这没有任何意义。操作系统(假设它工作正常)会在进程结束时自动为您清理任何内核对象,而不管进程结束的原因。
正如 Hans 所暗示的那样,ICLRPolicyManager当代码在特定主机(尤其是 SQL Server)中运行时,主机的 以这种方式确定哪些异常是致命的。请参阅本文档页面底部的漂亮网格:ICLRPolicyManager::SetActionOnFailure Method
| 归档时间: |
|
| 查看次数: |
1064 次 |
| 最近记录: |