Frage

Ich habe eine Klasse namens DatabaseHelper, die eine DbConnection wickelt. Was ist der richtige Weg, diese Klasse für eine using-Anweisung einrichten? Ich habe IDisposible implementiert, aber ich bin nicht sicher, wann und wo ich anrufen Connection.Close werden soll () oder Connection.Dispose ().

Wenn ich einfach anrufen Connection.Dispose () in meiner eigenen Methode Dispose (), werde ich manchmal eine Socket von meinem DbConnection Objekt erhalten. Ich nehme an, dies liegt daran, dass alte Verbindungen offen gelassen werden, aber es gibt keine Angaben über die zu Ausnahme angebracht ist, so kann ich nicht sicher wissen.

War es hilfreich?

Lösung

Rufen connection.Dispose () aus Ihrer dispose-Methode. Sie sollten für die Umsetzung IDisposable, bei dem Standardmuster suchen, die einfach über das hinaus geht die IDisposable-Schnittstelle implementiert und ermöglicht für die Entsorgung nicht verwalteten Objekte etc:

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);
}

(Aus http://msdn.microsoft.com/en -US / library / system.idisposable.aspx ).

Andere Tipps

Nach dieser Newsgroup:

Hier ist, wie IDbConnection.Dispose () (als Reflektor Dienstprogramm zeigt) implementiert:

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);
}

Ihre dispose-Methode sollte nur versuchen, die Verbindung zu schließen, wenn es geöffnet ist.

Diese destructor Syntax ist actualy der Finalizerthread. Die Finalizerthread ruft Dispose (false) Verfahren.

    #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

Es ist keine Notwendigkeit, der Finalizerthread (oder destructor) Syntax , bis Ihr Code hat Teil 2 Code . Ansonsten sollte es für die sichere Seite implementiert werden. dh, auch wenn der Programmierer die dispose-Methode nicht richtig aufrufen, finalisieren sollten die nicht verwalteten Ressourcen aufzuräumen.

Vergleichen Sie die Beispiele: Von Msdn

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

Sie einfach die IDisposable Implementierung Muster zu vervollständigen, ist es Konvention einen Finalizer (destructor) für Ihre Klasse enthalten, die die Methode Dispose () ruft (vorbei false). Dies dient als Sicherheitsmechanismus, so dass Sie von nicht verwalteten Objekten entsorgen, wenn die Verbraucher der Klasse Entsorgen Sie rufen nicht ().

    ~MyClass() 
    {
        Dispose(false);
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top