[英]IDisposable.Dispose is never called after exception in using block
我从像这样和这样的许多来源了解到,如果在Using
块中抛出异常,将始终调用IDisposable
的Dispose
方法。 那么我有这个代码:
static class MainEntryPoint
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
using (var x = new Disposable())
{
throw new Exception("asdfsdf");
}
}
private static void HandleUnhandledException(Object sender, System.UnhandledExceptionEventArgs e)
{
Environment.Exit(0);
}
}
class Disposable : IDisposable
{
public void Dispose()
{
System.Diagnostics.Debug.Print("I am disposed");
}
}
当抛出未处理的异常时,它退出应用程序。 从不调用Dispose
方法。 为什么?
Environment.Exit将终止程序
如果从 try 或 catch 块调用 Exit,则任何 finally 块中的代码都不会执行。 如果使用 return 语句,则 finally 块中的代码确实会执行。
using (var x = new Disposable())
{
throw new Exception("asdfsdf");
}
将被转换为
Disposable x = new Disposable();
try
{
throw new Exception("asdfsdf");
}
finally
{
if (x != null)
x.Dispose();
}
请注意,如果您向Disposable
添加了终结器,例如:
public class Disposable : IDisposable
{
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
Console.WriteLine("I am disposed");
if (disposing)
{
GC.SuppressFinalize(this);
}
}
~Disposable()
{
Dispose(false);
}
}
(因此使用“完整” IDisposable
模式),然后“通常”将调用终结器(因为终结器有机会在Environment.Exit
上运行),并且该方法将调用Dispose(bool disposing)
。 请注意,即使在这里也有可能不会运行终结器,因为它们有运行时间限制,请参阅。
确切地! 由于 Environment.Exit(0) 已在事件处理程序中调用,因此无法调用 Dispose 方法中的代码。
尝试删除对 Environment.Exit(0) 的调用并查看是否调用了 Debug.Print()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.