簡體   English   中英

.Net / C#對象是否應自行調用Dispose()?

[英]Should a .Net/C# object call Dispose() on itself?

下面是一位同事編寫的一些示例代碼。 這似乎對我來說顯然是錯誤的,但我想檢查一下。 對象應該從自己的方法之一中調用自己的Dispose()方法嗎? 在我看來,在處理完對象之后,只有對象的所有者/創建者才應調用Dispose() ,而不是對象本身。

這是一個.asmx網絡方法,完成后會自行對其調用Dispose() (這實際上是一個Web方法,實際上通常是這個問題附帶的。)在我們的代碼庫中,有時我們會在其他Web服務的方法中實例化Web服務類,然后在它們上調用方法。 如果我的代碼執行此操作來調用此方法,則該對象將在方法返回時吐司,並且我無法再使用該對象了。

[WebMethod]
public string MyWebMethod()
{
    try
    {
        return doSomething();
    }
    catch(Exception exception)
    {
        return string.Empty;
    }
    finally
    {
        Dispose(true);
    }
}

更新:找到了一些相關的鏈接:

我是否需要在ASP.NET中處理Web服務引用?

處置Web服務代理類?

當然,這不是一個好辦法。 調用方應決定何時使用IDisposable對象(而不是對象本身)完成操作。

如果我在自己的一個項目中看到它,我會問為什么,並且我99.9999%的確定我會刪除它

對我來說,這是一種紅旗/代碼的氣味

很少有有效的理由執行“自處置”操作。 線程是我經常使用的線程。

我有幾個“解雇”線程的應用程序。 使用這種方法可以使對象自行處置。

這有助於在沒有線程管理器進程的情況下保持環境的清潔。

對於允許的Dispose方法沒有技術限制。 唯一的特別之處是Dispose在某些構造中被調用( foreachusing )。 因此,可以合理地使用Dispose將對象標記為不再可用,尤其是在調用是冪等的情況下。

但是,由於Dispose接受了語義,因此我不會將其用於此目的。 如果我想從類本身內部將對象標記為不可再使用,那么我將創建一個可由Dispose或其他任何地方調用的MarkUnuseable()方法。

通過將對Dispose的調用限制為普遍接受的模式,可以購買到對所有類中的Dispose方法進行更改的能力,並確信您不會意外破壞任何偏離公共模式的代碼。

只需將其刪除,但要小心將其放置在所有調用它的對象中。

從技術上講,是的,如果該“方法”是終結器,並且您正在實現Microsoft指定的Finalize和IDisposable模式

雖然.Net對象通常不會自行調用Dispose,但有時在對象中運行的代碼可能是最后一個希望使用它的東西。 舉一個簡單的例子,如果Dispose方法可以處理部分構造的對象的清理,那么構造一個類似以下代碼的構造函數可能會很有用:

Sub New()
  Dim OK As Boolean = False
  Try
    ... do Stuff
    OK = True
  Finally
    If Not OK Then Me.Dispose
  End Try
End Sub

如果構造函數將拋出異常而沒有返回,那么將被廢棄的部分構造的對象將是唯一具有信息和動力進行必要清理的對象。 如果沒有確保及時處置,則別無所求。

對於您的特定代碼段,該模式有些不尋常,但看起來有點像套接字可以從一個線程傳遞到另一個線程的方式。 有一個調用返回一個字節數組並使Socket無效; 該字節數組可以在另一個線程中使用,以創建一個新的Socket實例,該實例接管另一個Socket建立的通信流。 請注意,有關打開套接字的數據實際上是非托管資源,但不能很好地將其包裝在帶有終結器的對象中,因為它通常會傳遞給垃圾收集器無法看到的內容。

沒有! 這是意外行為,並且違反了最佳做法准則。 切勿做任何意外的事情。 您的對象應僅執行維護其狀態所需的操作,同時為調用者​​保護對象的完整性。 調用方將決定完成的時間(如果沒有其他操作,則由GC決定)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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