簡體   English   中英

IDisposable.Dispose 在使用塊異常后永遠不會被調用

[英]IDisposable.Dispose is never called after exception in using block

我從像這樣這樣的許多來源了解到,如果在Using塊中拋出異常,將始終調用IDisposableDispose方法。 那么我有這個代碼:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM