2

DbConnection をラップする DatabaseHelper というクラスがあります。このクラスを using ステートメントにセットアップする適切な方法は何ですか? IDisposible を実装しましたが、いつどこで Connection.Close() または Connection.Dispose() を呼び出す必要があるかわかりません。

独自の Dispose() メソッドで単に Connection.Dispose() を呼び出すだけで、DbConnection オブジェクトから SocketException が発生することがあります。これは、古い接続が開いたままになっているためだと思いますが、例外に詳細が添付されていないため、確かなことはわかりません。

4

4 に答える 4

6

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から取得)。

于 2008-12-22T17:13:09.393 に答える
2

このニュースグループによると:

IDbConnection.Dispose() の実装方法は次のとおりです (Reflector ユーティリティが示すように)。

Sql クライアント:

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 メソッドは、接続が開いている場合にのみ接続を閉じようとする必要があります。

于 2008-12-22T17:18:33.203 に答える
1

このデストラクタ構文は、実際にはファイナライザです。ファイナライザーは 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.aspx & http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

于 2013-07-04T08:11:50.787 に答える
0

IDisposable 実装パターンを完成させるために、Dispose() メソッドを呼び出す (false を渡す) クラスのファイナライザー (デストラクタ) を含めるのが規則です。これはフェイルセーフ メカニズムとして機能し、クラスのコンシューマーが Dispose() の呼び出しに失敗した場合にアンマネージ オブジェクトを破棄できます。

    ~MyClass() 
    {
        Dispose(false);
    }
于 2008-12-22T20:00:11.457 に答える