2010-12-13 8 views
9

Załóżmy utworzyć zamknięcie nad zasobu takiego jak StreamWriter:F #: Pozbywanie się zasobów znajdujących się w zamknięciu?

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

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

Czy istnieje sposób, aby zamknąć StreamWriter kiedy skończę z zamknięciem? Czy muszę zastąpić zamknięcie obiektem wrappera, który ma metodę Write() i metodę Dispose()? (Jest to oczywiście trywializowany przykład). Dzięki wszystkim.

Odpowiedz

7

Tak, należy zastąpić zamknięcie obiektem IDisposable metodą i Dispose(). (Alternatywnie, zwraca krotki zamknięć, z których drugi nazywa Close() lub cokolwiek, i pozostawić go do rozmówcy w tym stylu.)

(Podczas gdy jesteś na to, System.IO.Path.Combine() powinien być stosowany zamiast klejenia razem nazw . z formatowaniem smyczkowy)

+0

Bardzo dziękuję Brian za szybką odpowiedź. Dostępne materiały F # wydają się mówić o zamknięciu i zarządzaniu zasobami, ale nie o dwóch razem. – FSharpN00b

3

czasami zrobić:

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

Dziękuję bardzo za odpowiedź dr Harrop. Wygląda na to, że powstrzymuje to proces otwierania pliku przed zamknięciem, ale nadal zamyka plik po zamknięciu zamknięcia. Wykorzystam to w przyszłości. – FSharpN00b

1

IDisposable wynosi około deterministycznie, czyli wyraźnie uwalniające zasoby. Jeśli więc zamknięcie nie zapewnia w jakiś sposób funkcjonalności wyrzucania przez siebie, zasobu nie można już dłużej uwalniać deterministycznie.

Jak zauważył Brian, może to być mniej lub bardziej jednoznaczne, chociaż wdrożenie IDisposable jest preferowane, ponieważ use + IDisposable automatycznie zajmuje się zwolnieniem zasobów w przypadku wyjątków.

Czasami wystarcza jednak całkowite ukrycie zasobu jednorazowego użytku i zamknięcie tego, co ma być zrobione.

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

// ... 

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

Dziękuję bardzo za odpowiedź Dario. Z tego, co słyszałem, zamknięcie jest reprezentowane jako kolejny obiekt .NET. Zastanawiam się, czy w pewnym momencie dostaniemy sposób, aby dodać do niego kod zakończenia/usunięcia. – FSharpN00b

Powiązane problemy