none
liberar recursos

    Pregunta

  • En una solucción con tres capas (Presentación, Datos Lógicos y Aceso a Datos), creo en la capa presentación una clase Cliente como indico al final. Mi duda es si es correcto liberar los recursos  tal como pongo en el código.
    
    Public Class ClasePruebaCliente
    
      Implements IDisposable
      Private objDLClientes As GesProDatosLogicos.DLClientes
      Private objDataSet As DataSet
      Private mIdCliente As Int32
      Private mNom As String
      Private disposedValue As Boolean = False    ' Para detectar llamadas redundantes
    
      ' IDisposable
      Private Overloads Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
          If disposing Then
            ' TODO: Liberar recursos administrados cuando se llamen explícitamente
            objDataSet.Dispose()
            objDataSet = Nothing
            mIdCliente = Nothing
            mNom = Nothing
          End If
          ' TODO: Liberar recursos no administrados compartidos
        End If
        Me.disposedValue = True
      End Sub
    
    #Region " IDisposable Support "
      ' Visual Basic agregó este código para implementar correctamente el modelo descartable.
      Public Overloads Sub Dispose() Implements IDisposable.Dispose
        ' No Modifique este código.
        ' Coloque el código de limpieza en Dispose(ByVal disposing As Boolean).
        Dispose(True)
        GC.SuppressFinalize(Me)
      End Sub
      Protected Overrides Sub Finalize()
        ' No Modifique este código.
        ' Coloque el código de limpieza en Dispose(ByVal disposing As Boolean).
        Dispose(False)
        MyBase.Finalize()
      End Sub
    
    #End Region
      Public Sub New(ByVal IdCliente As Int32)
        Using objDLClientes As New GesProDatosLogicos.DLClientes(g_strCadConnection)
          Try
            objDataSet = objDLClientes.getCliente(IdCliente)
            If objDataSet.Tables("tbCliente").Rows.Count = 0 Then Throw New Exception("No se encuentra el Cliente: " & IdCliente)
            mIdCliente = IdCliente
            mNom = objDataSet.Tables("tbCliente").Rows(0).Item("NomClie").ToString
          Catch ExceptionErr As Exception
            MessageBox.Show(ExceptionErr.Message, "AVISO")
          End Try
        End Using
      End Sub
    
      Public ReadOnly Property Id() As Integer
        Get
          Return mIdCliente
        End Get
      End Property
    
      Public ReadOnly Property Nombre() As String
        Get
          Return mNom
        End Get
      End Property
    End Class
    
    lunes, 02 de mayo de 2011 7:35

Respuestas

  • "AbuPepe" preguntó:

    > Mi duda es si es correcto liberar los recursos  tal como pongo en el código.

    > Private objDataSet As DataSet
    > Private mIdCliente As Int32
    > Private mNom As String
    >
    >  Private Overloads Sub Dispose(ByVal disposing As Boolean)
    >    If Not Me.disposedValue Then
    >      If disposing Then
    >        ' TODO: Liberar recursos administrados cuando se llamen explícitamente
    >        objDataSet.Dispose()
    >        objDataSet = Nothing
    >        mIdCliente = Nothing
    >        mNom = Nothing
    >      End If
    >      ' TODO: Liberar recursos no administrados compartidos
    >    End If
    >    Me.disposedValue = True
    >  End Sub

    Hola:

    Es parecido al código que automáticamente inserta Visual Studio cuando en una clase se implementa la interfaz IDisponsable, por lo que podíamos decir que es correcto que destruyas el objeto DataSet en la segunda sobrecarga del método Dispose, aunque puede que no sea necesario, dependiendo de la visibilidad que tenga la variable objeto que referencia a la instancia de la clase.

    Tampoco sería sumamente necesario establecer el valor Nothing a los distintos campos de la clase, aunque tampoco está mal que lo hagas de manera explícita, porque cuando se destruya la instancia de la clase, ese será el valor que tengan dichos campos.

    De todas maneras, te advierto que se ejecutará la parte de los recursos administrados del método Dispose únicamente cuando se le pase el valor True al parámetro «disposing», y ésto únicamente ocurrirá cuando se llame de manera explícita o implícitamente a dicho método; si no es así, nunca se ejecutará dicho código, porque cuando finalice la aplicación, se ejecutará el método Finalice, y éste le pasa un valor False al método Dispose.

    En definitiva, que se ejecutará el bloque

        If disposing Then

        End If

    cuando desde el código cliente se ejecute

        Dim c As New ClasePruebaCliente(IdCliente)

        c.Dispose()

    o bien utilices una instrucción Using ... End Using para declarar una nueva instancia de la clase:

        Usin c As New ClasePruebaCliente(IdCliente)

        End Using

    En el primer caso se llamará al método Dispose de manera explícita, y en el segundo se llamará de manera implícita.

    Otra cosa que observo en el código que has publicado, es que parece ser que solamente trabajas con un objeto DataTable, con lo cual, no sería necesario que declararas un objeto DataSet. Si es así, podrías sustituir la declaración del objeto DataSet por un objeto DataTable, y en lugar de ejecutar

         If objDataSet.Tables("tbCliente")

    ejecutarías

         If objDataTable("tbCliente")

    Un saludo

     


    Enrique Martínez
      [MS MVP - VB]

    • Marcado como respuesta AbuPepe lunes, 02 de mayo de 2011 8:54
    lunes, 02 de mayo de 2011 8:20
    Moderador

Todas las respuestas

  • "AbuPepe" preguntó:

    > Mi duda es si es correcto liberar los recursos  tal como pongo en el código.

    > Private objDataSet As DataSet
    > Private mIdCliente As Int32
    > Private mNom As String
    >
    >  Private Overloads Sub Dispose(ByVal disposing As Boolean)
    >    If Not Me.disposedValue Then
    >      If disposing Then
    >        ' TODO: Liberar recursos administrados cuando se llamen explícitamente
    >        objDataSet.Dispose()
    >        objDataSet = Nothing
    >        mIdCliente = Nothing
    >        mNom = Nothing
    >      End If
    >      ' TODO: Liberar recursos no administrados compartidos
    >    End If
    >    Me.disposedValue = True
    >  End Sub

    Hola:

    Es parecido al código que automáticamente inserta Visual Studio cuando en una clase se implementa la interfaz IDisponsable, por lo que podíamos decir que es correcto que destruyas el objeto DataSet en la segunda sobrecarga del método Dispose, aunque puede que no sea necesario, dependiendo de la visibilidad que tenga la variable objeto que referencia a la instancia de la clase.

    Tampoco sería sumamente necesario establecer el valor Nothing a los distintos campos de la clase, aunque tampoco está mal que lo hagas de manera explícita, porque cuando se destruya la instancia de la clase, ese será el valor que tengan dichos campos.

    De todas maneras, te advierto que se ejecutará la parte de los recursos administrados del método Dispose únicamente cuando se le pase el valor True al parámetro «disposing», y ésto únicamente ocurrirá cuando se llame de manera explícita o implícitamente a dicho método; si no es así, nunca se ejecutará dicho código, porque cuando finalice la aplicación, se ejecutará el método Finalice, y éste le pasa un valor False al método Dispose.

    En definitiva, que se ejecutará el bloque

        If disposing Then

        End If

    cuando desde el código cliente se ejecute

        Dim c As New ClasePruebaCliente(IdCliente)

        c.Dispose()

    o bien utilices una instrucción Using ... End Using para declarar una nueva instancia de la clase:

        Usin c As New ClasePruebaCliente(IdCliente)

        End Using

    En el primer caso se llamará al método Dispose de manera explícita, y en el segundo se llamará de manera implícita.

    Otra cosa que observo en el código que has publicado, es que parece ser que solamente trabajas con un objeto DataTable, con lo cual, no sería necesario que declararas un objeto DataSet. Si es así, podrías sustituir la declaración del objeto DataSet por un objeto DataTable, y en lugar de ejecutar

         If objDataSet.Tables("tbCliente")

    ejecutarías

         If objDataTable("tbCliente")

    Un saludo

     


    Enrique Martínez
      [MS MVP - VB]

    • Marcado como respuesta AbuPepe lunes, 02 de mayo de 2011 8:54
    lunes, 02 de mayo de 2011 8:20
    Moderador
  • Gracias Enrique, me quedó aclarada  la duda con tu completa explicación.

    A laa clase siempre las llamo con la instrucción  Using..end using.

    El objDataset  lo carga un procerdimiento almacenado en la capa de accesos a datos

    Saludos,


    lunes, 02 de mayo de 2011 8:56