簡體   English   中英

正確處理DbConnection

[英]Properly disposing of a DbConnection

我有一個名為DatabaseHelper的類,它包裝了一個DbConnection。 為using語句設置此類的正確方法是什么? 我已經實現了IDisposible,但我不確定我應該何時何地調用Connection.Close()或Connection.Dispose()。

當我在我自己的Dispose()方法中調用Connection.Dispose()時,我有時會從我的DbConnection對象中獲取SocketException。 我認為這是因為舊的連接處於打開狀態,但沒有附加到異常的詳細信息,所以我無法確定。

從dispose方法中調用connection.Dispose()。 您應該看一下實現IDisposable的標准模式,它超越了簡單地實現IDisposable接口並允許處理非托管對象等:

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if (!disposed)
    {
        if (disposing)
        {
            // Dispose managed resources.
        }

        // There are no unmanaged resources to release, but
        // if we add them, they need to be released here.
    }
    disposed = true;

    // If it is available, make the call to the
    // base class's Dispose(Boolean) method
    base.Dispose(disposing);
}

(摘自http://msdn.microsoft.com/en-us/library/system.idisposable.aspx )。

根據這個新聞組:

以下是IDbConnection.Dispose()的實現方式(如Reflector實用程序所示):

SqlClient中:

protected override void Dispose(bool disposing)
{
       if (disposing)
       {
             switch (this._objectState)
             {
                   case ConnectionState.Open:
                   {
                         this.Close();
                         break;
                   }
             }
             this._constr = null;
       }
       base.Dispose(disposing);
}

Odbc:
protected override void Dispose(bool disposing)
{
       if (disposing)
       {
             this._constr = null;
             this.Close();
             CNativeBuffer buffer1 = this._buffer;
             if (buffer1 != null)
             {
                   buffer1.Dispose();
                   this._buffer = null;
             }
       }
       base.Dispose(disposing);
}

OleDb:
protected override void Dispose(bool disposing)
{
       if (disposing)
       {
             if (this.objectState != 0)
             {
                   this.DisposeManaged();
                   if (base.DesignMode)
                   {
                         OleDbConnection.ReleaseObjectPool();
                   }
                   this.OnStateChange(ConnectionState.Open, ConnectionState.Closed);
             }
             if (this.propertyIDSet != null)
             {
                   this.propertyIDSet.Dispose();
                   this.propertyIDSet = null;
             }
             this._constr = null;
       }
       base.Dispose(disposing);
}

您的dispose方法只應嘗試在打開時關閉連接。

這個析構函數語法實際上是終結器。 終結器調用Dispose(false)方法。

    #region IDisposable Members
    private bool _isDisposed;

    private void ThrowIfDisposed()
    {
        if (_isDisposed)
            throw new ObjectDisposedException(this.GetType().Name);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                //part 1 : disposing managed objects
                _command.Dispose();
                _command.Connection.Dispose();
                if (_command.Transaction != null)
                    _command.Transaction.Dispose();
            }
            //part 2: disposing unmanged objects. Here there are no unmanged objects.
            _isDisposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    //~DbCommandExecutor() //No need of finalize here. Because there is no unmanged objects in my class. ie, no code in part 2.
    //{
    //    Dispose(false);
    //}
    #endregion

代碼具有第2部分代碼之前, 不需要終結器(或析構函數)語法。 否則應該為安全起見而實施。 即,即使程序員沒有正確調用dispose方法,finalize也應該清理非托管資源。

比較示例:來自msdn

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspxhttp://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

只是為了完成IDisposable實現模式,通常為您的類包含一個終結器(析構函數),它調用Dispose()方法(傳遞false)。 這充當故障保護機制,如果類的使用者無法調用Dispose(),則允許您處置非托管對象。

    ~MyClass() 
    {
        Dispose(false);
    }

暫無
暫無

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

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