Deconstructor de una clase con FileStream en CF1

08/02/2008 - 16:29 por Dario Salvi | Informe spam
Hola,

me pasa la siguiente cosa que no entiendo bien:

tengo una clase en Csharp en entorno CF 1 con un FileStream.

Al cerrar la clase me gustaría que el FileStream fuese cerrado bien o
sea con Flush y Close (quizas solo close basta?).

He hecho un metodo de Dispose que hace:

if (this.file != null)
{
this.file.Flush();
this.file.Close();
}
Y un deconstructor que simplemente llama al Dispose.

Ahora cuando el garbage collector llama al deconstructor en el dispose
me da: ObjectDisopsedException.

He leido un poco la documentación y dice que si la clase tiene objectos
unmanaged se provoca esta situacion. El FileStream es unmanaged? Que
tendría que hacer?

Muchas gracias...

Dario
 

Leer las respuestas

#1 Alberto Poblacion
09/02/2008 - 10:49 | Informe spam
"Dario Salvi" wrote in message
news:47ac74b1$
tengo una clase en Csharp en entorno CF 1 con un FileStream.

Al cerrar la clase me gustaría que el FileStream fuese cerrado bien o sea
con Flush y Close (quizas solo close basta?).

He hecho un metodo de Dispose que hace:

if (this.file != null)
{
this.file.Flush();
this.file.Close();
}
Y un deconstructor que simplemente llama al Dispose.

Ahora cuando el garbage collector llama al deconstructor en el dispose me
da: ObjectDisopsedException.



El Garbage Collector es impredecible a la hora de determinar el orden en
el que destruye los objetos. Si el "file" es inalcanzable y rueda el GC, lo
destruye, posiblemente antes de haber destruido tu clase. Cuando se destruye
tu clase y ésta intenta llamar al flush y el close de file, si éste ya
estaba destruido te da ese error.

En lugar de llamar a Flush y Close, llama a file.Dispose(). El Dispose,
si está bien programado, ya controla internamente si el objeto estaba
"disposed" para no "disposearlo" otra vez.

Adicionalmente, en tu código, cuando ya no necesites la clase, deberías
llamar a su Dispose, en lugar de confiar en que lo llame el finalizador. Y
en el dispose de tu clase deberías llamar a GC.SupressFinalize(), para que,
en caso de que todo haya ido bien y efectivamente hayas llamado al Dispose,
no se ejecute el Finalizador y éste trate de nuevo hacer un Dispose.

Preguntas similares