Dispose()

30/10/2004 - 23:30 por Enrique | Informe spam
Hola Grupo

Como hago para que se destruya mi objeto (uno creado por mi)?
Yo le puse la interfaz IDisposable, y en el metodo Dispose() ejecuto
GC.Collect(), y pongo en null todas las variables incluyendo el mismo
objeto? Esta bien eso?

Preguntas similare

Leer las respuestas

#1 Hector Bejarano
31/10/2004 - 04:04 | Informe spam
Hola Enrique,

Este es un ejemplo tomado del libro "Developing Web Services and Server
components with VB.NET and C#.NET" de Microsoft Press.

El ejemplo que estoy poniendo esta en C#, es importante que no pierdas de
vista un concepto clave, si pones el objeto en null antes de realizar un
Dispose(), lo que realmente estas haciendo es poniendo en null la direccion
de memoria en donde se encuentra el objeto, no estas liberando los recursos
que este utiliza.

// Implementing IDisposable implies that the
// instances of this class will use unmanaged resources

public class Parent:IDisposable
{
// An unmanaged resource
private IntPtr ptr;

// A Managed resource
private System.Timers.Timer timer;

// Variable to track call to Dispose method
private bool disposed;

public Parent()
{
// Implement constructor

}

public void Dispose()
{
// Call the overloaded Dispose method
// with true as argument, indicating that
// Dispose is called by the user of the object
Dispose(true);
// Suppress the Finalize method
// so that it does not call Dispose again
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool called_by_user )
{
if (!this.disposed)
{
// if the user of the object called the Dispose method
// Clean managed as well as unmanaged data
// Otherwise clean only unmanaged data
if (called_by_user)
{
// Clean managed data
timer.Dispose();
}
ptr = IntPtr.Zero;
disposed = true;
}
}
// C# destructor which is used to execute the finalization code
~Parent()
{
Dispose(false);
}

}

public class Child:Parent
{.
.
.

protected override void Dispose(bool called_by_user)
{
// Cleanup code for the child object
.
.
.

// Call Dispose method of the Parent class
base.Dispose(called_by_user);

}

}Despues de realizer la liberacion de los recursos, el garbage collector
va a determinar que los objetos no son alcanzables, y va a liberar la
memoria.Hector Bejarano."Enrique" wrote in message
news:%23$ Hola Grupo

Como hago para que se destruya mi objeto (uno creado por mi)?
Yo le puse la interfaz IDisposable, y en el metodo Dispose() ejecuto
GC.Collect(), y pongo en null todas las variables incluyendo el mismo
objeto? Esta bien eso?

Respuesta Responder a este mensaje
#2 Enrique
31/10/2004 - 19:26 | Informe spam
Gracias por tu respuesta
Entonces yo con ese codigo sacaria todos los eventos a los que accedia ese
objeto y se cerrarian los Sockets por ej.?


"Hector Bejarano" escribió en el mensaje
news:e%
Hola Enrique,

Este es un ejemplo tomado del libro "Developing Web Services and Server
components with VB.NET and C#.NET" de Microsoft Press.

El ejemplo que estoy poniendo esta en C#, es importante que no pierdas de
vista un concepto clave, si pones el objeto en null antes de realizar un
Dispose(), lo que realmente estas haciendo es poniendo en null la
direccion de memoria en donde se encuentra el objeto, no estas liberando
los recursos que este utiliza.

// Implementing IDisposable implies that the
// instances of this class will use unmanaged resources

public class Parent:IDisposable
{
// An unmanaged resource
private IntPtr ptr;

// A Managed resource
private System.Timers.Timer timer;

// Variable to track call to Dispose method
private bool disposed;

public Parent()
{
// Implement constructor

}

public void Dispose()
{
// Call the overloaded Dispose method
// with true as argument, indicating that
// Dispose is called by the user of the object
Dispose(true);
// Suppress the Finalize method
// so that it does not call Dispose again
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool called_by_user )
{
if (!this.disposed)
{
// if the user of the object called the Dispose method
// Clean managed as well as unmanaged data
// Otherwise clean only unmanaged data
if (called_by_user)
{
// Clean managed data
timer.Dispose();
}
ptr = IntPtr.Zero;
disposed = true;
}
}
// C# destructor which is used to execute the finalization code
~Parent()
{
Dispose(false);
}

}

public class Child:Parent
{.
.
.

protected override void Dispose(bool called_by_user)
{
// Cleanup code for the child object
.
.
.

// Call Dispose method of the Parent class
base.Dispose(called_by_user);

}

}Despues de realizer la liberacion de los recursos, el garbage collector
va a determinar que los objetos no son alcanzables, y va a liberar la
memoria.Hector Bejarano."Enrique" wrote in message
news:%23$ Hola Grupo

Como hago para que se destruya mi objeto (uno creado por mi)?
Yo le puse la interfaz IDisposable, y en el metodo Dispose() ejecuto
GC.Collect(), y pongo en null todas las variables incluyendo el mismo
objeto? Esta bien eso?





Respuesta Responder a este mensaje
#3 Octavio Hernandez
01/11/2004 - 10:48 | Informe spam
Enrique,

- En general, no tiene sentido invocar al recolector de basura cada vez que
destruyas un objeto. La idea es que este se dispare cuando el sistema lo
crea necesario...
- Si tu clase utiliza recursos no manejados, como sockets, en el método
Dispose() debes comprobar que están cerrados y si es necesario hacer las
llamadas a los métodos Close() correspondientes.
- Para "destruir" un objeto de esa clase, aplícale el método Dispose(). Y
luego asigna null a la variable, para que el objeto se convierta en "basura"
inmediatamente (de lo contrario, se convertirá en basura cuando la variable
salga de ámbito):

MiObjeto.Dispose();
MiObjeto = null;

- Si utilizas la sentencia using, el compilador hará la llamada a Dispose()
por tí:

using (MiObjeto obj = new MiObjeto())
{
// trabajo con obj
}

Slds - Octavio

"Enrique" escribió en el mensaje
news:%23$
Hola Grupo

Como hago para que se destruya mi objeto (uno creado por mi)?
Yo le puse la interfaz IDisposable, y en el metodo Dispose() ejecuto
GC.Collect(), y pongo en null todas las variables incluyendo el mismo
objeto? Esta bien eso?


Respuesta Responder a este mensaje
#4 Enrique
01/11/2004 - 12:07 | Informe spam
Gracias Octavio, pero no me quedo muy claro lo de utilizar la sentencia
using :(. Y otra cosa... osea que yo tendria que incluir en mi Dispose() los
object.Close() y object.evento -= ?


"Octavio Hernandez" escribió en el mensaje
news:eCRjqf$
Enrique,

- En general, no tiene sentido invocar al recolector de basura cada vez
que
destruyas un objeto. La idea es que este se dispare cuando el sistema lo
crea necesario...
- Si tu clase utiliza recursos no manejados, como sockets, en el método
Dispose() debes comprobar que están cerrados y si es necesario hacer las
llamadas a los métodos Close() correspondientes.
- Para "destruir" un objeto de esa clase, aplícale el método Dispose(). Y
luego asigna null a la variable, para que el objeto se convierta en
"basura"
inmediatamente (de lo contrario, se convertirá en basura cuando la
variable
salga de ámbito):

MiObjeto.Dispose();
MiObjeto = null;

- Si utilizas la sentencia using, el compilador hará la llamada a
Dispose()
por tí:

using (MiObjeto obj = new MiObjeto())
{
// trabajo con obj
}

Slds - Octavio

"Enrique" escribió en el mensaje
news:%23$
Hola Grupo

Como hago para que se destruya mi objeto (uno creado por mi)?
Yo le puse la interfaz IDisposable, y en el metodo Dispose() ejecuto
GC.Collect(), y pongo en null todas las variables incluyendo el mismo
objeto? Esta bien eso?






Respuesta Responder a este mensaje
#5 Octavio Hernandez
01/11/2004 - 12:45 | Informe spam
Enrique,

osea que yo tendria que incluir en mi Dispose() los object.Close() y




object.evento -= ?

a) Ten en cuenta que en la POO una clase puede utilizar a otra de dos
maneras: como heredero (heredando de ella) o como cliente (incluyendo una
instancia de ella).
1. Si estás utilizando la herencia, por ejemplo si creas una clase MiSocket
que hereda de Socket, lo más probable es que no necesites programar el
Dispose() porque ya la clase base lo tiene, y tú podrás llamarlo
directamente cuando vayas a "destruir" tu objeto:

DECLARACION:
public MiSocket: Socket
{
// constructor
public MiSocket(): base() // aquí se llama al constructor de Socket
{
// inicialización de tu clase
}
// ... más ...
// no hay que definir Dispose(), pues ya se hereda de Socket
}

USO:

MiSocket s = new MiSocket();
// ...
s.Dispose();
s = null;

2. Si tu clase no hereda de Socket, sino que dentro de tu clase has
declarado un objeto de la clase Socket, entonces tú eres el responsable de
crear y destruir ese campo:

DECLARACION:
public MiSocket : IDisposable // no hereda de Socket, pero implementa
IDisposable
{
private Socket s; // campo privado
// constructor
public MiSocket()
{
s = new Socket(); // creación del objeto interno
// más inicializaciones...
}
// hay que definir Dispose(),
// y lo más correcto es que también haya un finalizador...
private bool disposed = false; // variable que te dirá si ya se ha
hecho Dispose(), para no hacerlo dos veces...
public void Dispose()
{
if (!disposed)
{
s.Close();
disposed = true;
}
// finalizador
~MiSocket()
{
Dispose();
}
}

USO:

MiSocket s = new MiSocket();
// ...
s.Dispose();
s = null;

Fíjate que en ambos casos, cuando alguien esté usando un objeto de la clase
y termine de trabajar con él simplemente deberá aplicarle Dispose(). Esto
hace posible que la gente utilice tu clase sin importarle cómo ha sido
programada.

Y todo esto que estamos hablando tiene que ver con clases que utilizan
recursos no-manejados, como sockets, ficheros, mapas de bits o conexiones a
bases de datos. Si la clase utiliza únicamente recursos manejados (objetos
en memoria) lo más probable es que no haga falta incluirle un Dispose(),
dejando al recolector de basura la tarea de liberarlos.

El tema es un tema complejo pero que hay que comprender bien, te recomiendo
seguir buscando información en la web o libros de C#. Lo del using déjalo
para más adelante, pues además de esto de Dispose() para entenderlo bien
hace falta tener claros otros conceptos, como el try/finally...

Slds - Octavio
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida