Question

J'ai une classe appelée DatabaseHelper qui enveloppe un DbConnection. Quelle est la bonne façon de configurer cette classe pour une instruction à l'aide? Je l'ai mis en œuvre IDisposible, mais je ne sais pas quand et où j'appellerai Connection.Close () ou Connection.Dispose ().

Quand j'appelle simplement Connection.Dispose () dans ma propre méthode Dispose (), je vais parfois obtenir un SocketException de mon objet DbConnection. Je suppose que cela est parce que les vieux connexions sont laissées ouvertes, mais il n'y a pas de détails attachés à l'exception, donc je ne peux pas en être sûr.

Était-ce utile?

La solution

Appel connection.Dispose () à partir de votre méthode dispose. Vous devriez regarder le modèle standard pour la mise en œuvre IDisposable, qui va au-delà de la mise en œuvre simplement l'interface IDisposable et permet de disposer d'objets non gérés 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);
}

(Extrait du http://msdn.microsoft.com/en -nous / bibliothèque / system.idisposable.aspx).

Autres conseils

Selon ce forum :

Voici comment IDbConnection.Dispose () est mis en œuvre (comme le montre l'utilité du réflecteur):

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

Votre méthode ne devrait tenter Éliminez de fermer la connexion si elle est ouverte.

Cette syntaxe est destructor le finaliseur actualy. Le finaliseur appelle Dispose (false) méthode.

    #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

Il est pas besoin de la syntaxe finaliseur (ou destructor) jusqu'à ce que votre code a le code partie 2 . Dans le cas contraire, il devrait être mis en œuvre pour le côté sécuritaire. à-dire, même si le programmeur ne demande pas la méthode éliminer de manière appropriée, devrait finaliser nettoyer les ressources non gérées.

comparer les exemples: De msdn

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

Juste pour compléter le modèle de mise en œuvre IDisposable, il est d'inclure une convention finaliseur (destructor) pour votre classe qui appelle la méthode Dispose () (passage faux). Cela agit comme un mécanisme de sécurité, ce qui vous permet de disposer d'objets non gérés si le consommateur de la classe n'appeler Dispose ().

    ~MyClass() 
    {
        Dispose(false);
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top