2010-12-13 13 views
9

Supongamos que se crea un cierre sobre un recurso como un StreamWriter:F #: ¿Desechar los recursos que están dentro de un cierre?

let currentdir = Directory.GetCurrentDirectory() 
let testfile = sprintf "%s\\%s" currentdir "closuretest.txt" 

let getwriter() = 
    let writer = new StreamWriter(testfile, false) 
    (fun() -> writer.Write "test") 

¿Hay una manera de cerrar la StreamWriter cuando he terminado con el cierre? ¿O necesito reemplazar el cierre con un objeto contenedor que tenga un método Write() y un método Dispose()? (Esto es, por supuesto, un ejemplo trivializado.) Gracias a todos.

Respuesta

7

Sí, debe reemplazar el cierre con un objeto IDisposable con un método y un Dispose(). (Alternativamente, devolver una tupla de cierres, la segunda de las cuales llama Close() o lo que sea, y dejar que la persona que llama por el estilo.)

(Mientras estás en ello, System.IO.Path.Combine() se debe utilizar, en lugar de pegar juntos los nombres de archivo . con el formato de cadenas)

+0

Muchas gracias Brian por la respuesta rápida. El material F # disponible parece referirse a cierres y gestión de recursos, pero no a los dos juntos. – FSharpN00b

3

hago a veces:

let getwriter() = 
    let writer = new StreamWriter(testfile, false) 
    (fun() -> 
    use writer = writer 
    writer.Write "test") 
+0

Muchas gracias por su respuesta, Dr. Harrop. Parece que mantiene el trabajo de abrir el archivo fuera del cierre, y aún así cierra el archivo cuando finaliza el cierre. Lo usaré en el futuro. – FSharpN00b

1

IDisposable es de unos forma determinista, es decir, la liberación de los recursos de forma explícita. Por lo tanto, si el cierre no proporciona de alguna manera una funcionalidad de eliminación por sí mismo, el recurso ya no se puede liberar de forma determinista.

Como señaló Brian, esto puede ser más o menos explícito, aunque la implementación de IDisposable es preferible como use + IDisposable se ocupa automáticamente de liberar recursos en caso de excepciones.

Sin embargo, a veces es suficiente para ocultar por completo el recurso desechable y obtener un cierre de lo que se debe hacer en su lugar.

let getWriter body = 
    use writer = new StreamWriter(testfile, false) 
    body(writer) 

// ... 

getWriter (fun writer -> writer.Write "test") 
+0

Muchas gracias por su respuesta Darío. Por lo que he escuchado, un cierre se representa simplemente como otro objeto .NET. Me pregunto si en algún momento obtendremos una forma de agregar el código de finalización/eliminación. – FSharpN00b

Cuestiones relacionadas