IDisposable.Dispose 在 using 块出现异常后永远不会被调用
IDisposable.Dispose is never called after exception in using block
我从 this and this 等许多来源了解到,如果在 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 将终止程序
If Exit is called from a try or catch block, the code in any finally
block does not execute. If the return statement is used, the code in
the finally block does execute.
using (var x = new Disposable())
{
throw new Exception("asdfsdf");
}
将转换为
Disposable x = new Disposable();
try
{
throw new Exception("asdfsdf");
}
finally
{
if (x != null)
x.Dispose();
}
没错!由于在事件处理程序中调用了 Environment.Exit(0),因此无法调用 Dispose 方法中的代码。
尝试删除对 Environment.Exit(0) 的调用并查看是否调用了 Debug.Print()。
请注意,如果您已将终结器添加到 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);
}
}
(因此使用 "full" IDisposable
模式),然后 "normally" 终结器将被调用(因为终结器有机会 运行 在 Environment.Exit
),该方法将调用 Dispose(bool disposing)
。请注意,即使在这里,终结器也有可能不是 运行,因为它们有时间限制 运行、see.
我从 this and this 等许多来源了解到,如果在 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 将终止程序
If Exit is called from a try or catch block, the code in any finally block does not execute. If the return statement is used, the code in the finally block does execute.
using (var x = new Disposable())
{
throw new Exception("asdfsdf");
}
将转换为
Disposable x = new Disposable();
try
{
throw new Exception("asdfsdf");
}
finally
{
if (x != null)
x.Dispose();
}
没错!由于在事件处理程序中调用了 Environment.Exit(0),因此无法调用 Dispose 方法中的代码。
尝试删除对 Environment.Exit(0) 的调用并查看是否调用了 Debug.Print()。
请注意,如果您已将终结器添加到 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);
}
}
(因此使用 "full" IDisposable
模式),然后 "normally" 终结器将被调用(因为终结器有机会 运行 在 Environment.Exit
),该方法将调用 Dispose(bool disposing)
。请注意,即使在这里,终结器也有可能不是 运行,因为它们有时间限制 运行、see.