Nuevos objetos como parámetros... y posterior liberación...

26/02/2006 - 17:41 por Sergio | Informe spam
Hola:

Si para un método que necesita recibir un parámetro de tipo
FileStream, escribo algo así:

método(New FileStream("C:\Archivo.txt", IO.FileMode.OpenOrCreate))

¿Se liberaría después de el objeto FileStream? Es decir, imagino que
sería más adecuado hacer algo así:

Dim a As New FileStream("C:\Archivo.txt", IO.FileMode.OpenOrCreate)
método(a)
a.Close
a.Dispose

Ya se que cuando llegue el recolector de basura liberará los objetos
no referenciados, pero, por norma y para hacerlo extensible a cualquier
ejemplo similar al anterior

¿Qué es más optimo y adecuado, el ejemplo 1 o el 2?
¿Vosotros como lo haceís?

Gracias y un saludo.

Preguntas similare

Leer las respuestas

#1 Jorge Serrano [MVP VB]
26/02/2006 - 18:17 | Informe spam
Hola Sergio,

yo siempre acostumbro a cerrar los objetos.

El recolector de basura mirará los objetos referenciados y liberados y se
encargará de limpiarlos de la memoria sino se utilizan en un periodo de
tiempo.

A mí me gusta siempre abrir el objeto y cerrarlo si se que no lo voy a
utilizar o que casi seguro que no lo voy a usar más.

Pero sobre gustos...

Un saludo.

Jorge Serrano Pérez
Microsoft MVP VB.NET
PortalVB.com
http://www.portalvb.com/
Weblog de Jorge Serrano
http://weblogs.golemproject.com/jorge/


"Sergio" wrote:

Hola:

Si para un método que necesita recibir un parámetro de tipo
FileStream, escribo algo así:

método(New FileStream("C:\Archivo.txt", IO.FileMode.OpenOrCreate))

¿Se liberaría después de el objeto FileStream? Es decir, imagino que
sería más adecuado hacer algo así:

Dim a As New FileStream("C:\Archivo.txt", IO.FileMode.OpenOrCreate)
método(a)
a.Close
a.Dispose

Ya se que cuando llegue el recolector de basura liberará los objetos
no referenciados, pero, por norma y para hacerlo extensible a cualquier
ejemplo similar al anterior

¿Qué es más optimo y adecuado, el ejemplo 1 o el 2?
¿Vosotros como lo haceís?

Gracias y un saludo.


Respuesta Responder a este mensaje
#2 Patxi Sanz
27/02/2006 - 13:36 | Informe spam
Hola Sergio:

Debes tener muy en cuenta lo que dice Jorge Serrano:

A mí me gusta siempre abrir el objeto y cerrarlo si se que no lo voy a


utilizar o que casi seguro que no lo voy a usar más.

Como casi todos los parámetros de los métodos se pasan por referencia (sobre
todo si son clases), si destruyes la clase que has pasado a un método justo
después de llamarlo, es posible que ese método ya no te funcione, o que al
llamar a otro método que necesitaría de la clase pasada anteriormente, no
haga lo que debe.

Me parece que así no me entenderás ;-), así que te voy a dar un ejemplo para
explicarme mejor:

Crea una aplicación para Windows, y en el form principal crea dos botones
(Button1 y Button2). Después copia y pega el siguiente código en el código
del formulario:

Public Class Form1
Private prueba As ClasePrueba

'En esta Sub SÍ me fío del recolector de basuras
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
prueba.Comenzar(New System.Timers.Timer(5000))
End Sub

'En esta Sub NO me fío del recolector de basuras
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Dim tmr As System.Timers.Timer
tmr = New System.Timers.Timer(5000)
prueba.Comenzar(tmr)
tmr.Dispose()
End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
prueba = New ClasePrueba
End Sub
End Class

Public Class ClasePrueba
Private WithEvents x As System.Timers.Timer

Private Sub TiempoTrancurrido(ByVal sender As Object, ByVal e As
System.Timers.ElapsedEventArgs) Handles x.Elapsed
MessageBox.Show("Ha transcurrido el tiempo")
x.Stop()
End Sub

Public Sub Comenzar(ByVal tmr As System.Timers.Timer)
x = tmr
AddHandler x.Elapsed, AddressOf TiempoTrancurrido
x.Start()
End Sub
End Class

Lo que hace el código es muy sencillo: al pulsar un botón, se llama al
método Comenzar() de ClasePrueba, que cuenta el tiempo y después muestra un
mensaje. Pero, si se usa el segundo botón no se muestra el mensaje, ¿por
qué? Porque se ha destruido la referencia de la clase Timer en el evento de
ese botón y, como se pasa por referencia, también se destruye la referencia
de la clase Timer en la clase ClasePrueba.

Espero que así haya quedado más claro lo que he intentado decirte.

Un saludo,


Patxi Sanz
patxisanz[ARROBA]yahoo[PUNTO]es
Tudela (NA)
Respuesta Responder a este mensaje
#3 Sergio León
01/03/2006 - 08:13 | Informe spam
Gracias, después de leer vuestros consejos voy a utilizar siempre la
declaración, inicialización y posterior liberación manual para evitar
problemas y estar seguro de que los objetos se liberan correctamente.

"Patxi Sanz" <patxisanz[ARROBA]yahoo[PUNTO]es> escribió en el mensaje
news:%
Hola Sergio:

Debes tener muy en cuenta lo que dice Jorge Serrano:

A mí me gusta siempre abrir el objeto y cerrarlo si se que no lo voy a


utilizar o que casi seguro que no lo voy a usar más.

Como casi todos los parámetros de los métodos se pasan por referencia
(sobre todo si son clases), si destruyes la clase que has pasado a un
método justo después de llamarlo, es posible que ese método ya no te
funcione, o que al llamar a otro método que necesitaría de la clase pasada
anteriormente, no haga lo que debe.

Me parece que así no me entenderás ;-), así que te voy a dar un ejemplo
para explicarme mejor:

Crea una aplicación para Windows, y en el form principal crea dos botones
(Button1 y Button2). Después copia y pega el siguiente código en el código
del formulario:

Public Class Form1
Private prueba As ClasePrueba

'En esta Sub SÍ me fío del recolector de basuras
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
prueba.Comenzar(New System.Timers.Timer(5000))
End Sub

'En esta Sub NO me fío del recolector de basuras
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Dim tmr As System.Timers.Timer
tmr = New System.Timers.Timer(5000)
prueba.Comenzar(tmr)
tmr.Dispose()
End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
prueba = New ClasePrueba
End Sub
End Class

Public Class ClasePrueba
Private WithEvents x As System.Timers.Timer

Private Sub TiempoTrancurrido(ByVal sender As Object, ByVal e As
System.Timers.ElapsedEventArgs) Handles x.Elapsed
MessageBox.Show("Ha transcurrido el tiempo")
x.Stop()
End Sub

Public Sub Comenzar(ByVal tmr As System.Timers.Timer)
x = tmr
AddHandler x.Elapsed, AddressOf TiempoTrancurrido
x.Start()
End Sub
End Class

Lo que hace el código es muy sencillo: al pulsar un botón, se llama al
método Comenzar() de ClasePrueba, que cuenta el tiempo y después muestra
un mensaje. Pero, si se usa el segundo botón no se muestra el mensaje,
¿por qué? Porque se ha destruido la referencia de la clase Timer en el
evento de ese botón y, como se pasa por referencia, también se destruye la
referencia de la clase Timer en la clase ClasePrueba.

Espero que así haya quedado más claro lo que he intentado decirte.

Un saludo,


Patxi Sanz
patxisanz[ARROBA]yahoo[PUNTO]es
Tudela (NA)


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida