[我从this和this等许多来源了解,如果Dispose
块中引发异常,则将始终调用IDisposable
的Using
方法。因此,我有了这段代码:
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,则任何块不执行。如果使用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)
。请注意,即使在这里,终结器也有可能无法运行,因为它们有运行时间的限制see。
是!因为在事件处理程序中已调用Environment.Exit(0),所以将无法调用Dispose方法中的代码。
尝试删除对Environment.Exit(0)的调用,看看是否调用了Debug.Print()。