簡體   English   中英

Dispose()是否應該創建新的對象實例?

[英]Should Dispose() ever create new instances of objects?

使用C#.NET 4.0

我公司的應用程序使用資源鎖定器來保持記錄不被同時編輯。 我們使用數據庫來存儲鎖的開始時間以及獲取鎖的用戶。 這導致在資源鎖定器上執行以下(奇怪的?)dispose,這恰好是從析構函數調用的:

protected virtual void Dispose(bool disposing)
        {
            lock (this)
            {
                if (lockid.HasValue)
                {
                    this.RefreshDataButtonAction = null;
                    this.ReadOnlyButtonAction = null;

                try
                {
                    **Dictionary<string, object> parameters = new Dictionary<string, object>();
                    parameters.Add("@lockID", lockid.Value);
                    parameters.Add("@readsToDelete", null);
                    Object returnObject = dbio2.ExecuteScalar("usp_DeleteResourceLockReads", parameters);**

                    lockid = null;
                }
                catch (Exception ex)
                {
                    Logger.WriteError("ResourceLockingController", "DeleteResourceLocks", ex);
                }
                finally
                {
                    ((IDisposable)_staleResourcesForm).Dispose();
                    _staleResourcesForm = null;
                }
            }
        }
    }

我擔心粗體部分我們因為從數據庫調用中記錄了奇怪的“Handle is not initialized”異常。 我在其他地方讀到在Finalize()期間創建新對象是不安全的,但同樣的規則是否適用於dispose()? 在Dispose()期間是否有任何可能的副作用伴隨創建新對象?

與任何其他方法一樣, Dispose只是一種方法。 關於它應該/不應該做的事情有一些約定,但從系統的角度來看,在Dispose調用中創建對象是錯誤的。

進行數據庫調用對於個人而言有點令人擔憂; 我不希望在Dispose方法中調用這樣昂貴且容易出錯的活動,但這更像是一種約定/期望。 系統不會有問題。

是的,但除非創建的對象在方法的本地范圍內,否則我不會這樣做。 IDisposable是一個廣告,該類具有一些資源(通常是非托管資源),當不再使用該對象時應該釋放該資源。 如果您的Finializer正在調用您的Dispose(即您沒有直接調用析構函數,而是等待GC執行它),則可能表示您應該提前調用它。 您永遠不知道C#析構函數何時運行,因此您可能會不必要地占用該資源。 它也可能表明您的類不需要實現IDisposable。

在您的情況下,您正在使用對象dbio2,我假設它代表您的數據庫連接。 但是,由於這是從析構函數調用的,您如何知道您的連接是否仍然有效? 您的析構函數可能在您的連接丟失后一小時。 在知道dbio2對象仍在范圍內時,應該嘗試確保調用此Dispose。

這恰好是從析構函數中調用的

這是真正的問題。 您不能假設* dbio2“對象本身尚未最終確定。最終化順序在.NET中不具有確定性。結果看起來很像您描述的,dbase提供程序使用的內部句柄將被釋放,因此”處理未初始化“預期異常。或者dbio2對象已經被處理掉了。

這在程序退出時尤其可能出錯。 當終結器線程的2秒超時時,你也會遇到問題,dbase操作可以輕松獲得更多。

你根本無法依靠終結器來為你做這件事。 必須檢查配置的參數,而不是調用dbio2.ExecuteScalar()方法時,它是假的。 這可能也結束了析構函數的用處。

暫無
暫無

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

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