Pregunta

Tengo una clase llamada DatabaseHelper que envuelve un DbConnection. ¿Cuál es la forma correcta de configuración de esta clase para una instrucción using? He implementado IDisposible, pero no estoy seguro de cuándo y dónde debería estar llamando Connection.close () o Connection.Dispose ().

Cuando yo simplemente llamo Connection.Dispose () en mi propio método Dispose (), voy a veces sale un SocketException de mi objeto DbConnection. Supongo que esto se debe a que las antiguas conexiones se están quedando abierta, pero no hay detalles adjuntos a la excepción, así que no puedo saber con seguridad.

¿Fue útil?

Solución

Llamada connection.Dispose () desde dentro de su método dispose. Usted debe buscar en el patrón estándar para implementar IDisposable, que va más allá de la simple aplicación de la interfaz IDisposable y permite la eliminación de objetos no administrados 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);
}

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

Otros consejos

De acuerdo con este grupo de noticias :

Aquí es cómo se implementa IDbConnection.Dispose () (como muestra la utilidad 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);
}

Su método dispose sólo debe tratar de cerrar la conexión si está abierto.

Esta sintaxis destructor Es en realidad el finalizador. El finalizador está llamando Desechar (falso) método.

    #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

hay necesidad del finalizador (o destructor) sintaxis hasta que su código tiene la parte 2 de código . De lo contrario, debe ser implementado por el lado seguro. es decir, a pesar de que el programador no está llamando al método dispose correctamente, debe finalizar limpiar los recursos no administrados.

comparar los ejemplos: A partir de MSDN

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

Sólo para completar el patrón de aplicación IDisposable, que es la convención de incluir un finalizador (destructor) para su clase que llama al método Dispose () (que pasa a falso). Esto actúa como un mecanismo a prueba de fallos, lo que le permite disponer de objetos no administrados si el consumidor de la clase no puede llamar a Dispose ().

    ~MyClass() 
    {
        Dispose(false);
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top