Zarządzanie zasobami: use — Słowo kluczowe

W tym temacie opisano słowo kluczowe use i using funkcję, które mogą kontrolować inicjowanie i wydawanie zasobów.

Zasoby

Termin zasób jest używany w więcej niż jeden sposób. Tak, zasoby mogą być danymi używanymi przez aplikację, takimi jak ciągi, grafika i podobne, ale w tym kontekście zasoby odnoszą się do zasobów oprogramowania lub systemu operacyjnego, takich jak konteksty urządzeń graficznych, dojścia plików, połączenia sieciowe i bazy danych, obiekty współbieżności, takie jak uchwyty oczekiwania itd. Użycie tych zasobów przez aplikacje obejmuje nabycie zasobu z systemu operacyjnego lub innego dostawcy zasobów, a następnie późniejsze wydanie zasobu do puli, aby można było udostępnić go innej aplikacji. Problemy występują, gdy aplikacje nie zwalniają zasobów z powrotem do wspólnej puli.

Zarządzanie zasobami

Aby efektywnie i odpowiedzialnie zarządzać zasobami w aplikacji, należy szybko i w przewidywalny sposób zwolnić zasoby. Program .NET Framework pomaga w tym celu, udostępniając System.IDisposable interfejs. Typ implementujący System.IDisposable ma metodę System.IDisposable.Dispose , która poprawnie zwalnia zasoby. Dobrze napisane aplikacje gwarantują, że System.IDisposable.Dispose jest wywoływany szybko, gdy dowolny obiekt, który zawiera ograniczony zasób, nie jest już potrzebny. Na szczęście większość języków platformy .NET zapewnia obsługę ułatwiania tego, a język F# nie jest wyjątkiem. Istnieją dwie przydatne konstrukcje językowe, które obsługują wzorzec usuwania: use powiązanie i using funkcję.

korzystanie z powiązania

Słowo use kluczowe ma postać podobną let do powiązania:

użyj wyrażenia wartości =

Zapewnia tę samą funkcjonalność co let powiązanie, ale dodaje wywołanie wartości Dispose , gdy wartość wykracza poza zakres. Należy pamiętać, że kompilator wstawia sprawdzanie wartości null, więc jeśli wartość to null, wywołanie Dispose metody nie zostanie podjęta.

W poniższym przykładzie pokazano, jak automatycznie zamknąć plik przy użyciu słowa kluczowego use .

open System.IO

let writetofile filename obj =
   use file1 = File.CreateText(filename)
   file1.WriteLine("{0}", obj.ToString() )
   // file1.Dispose() is called implicitly here.

writetofile "abc.txt" "Humpty Dumpty sat on a wall."

Wiele wystąpień klasy jest usuwanych w odwrotnej use kolejności, w której są deklarowane. Oznacza to, że pierwszy use będzie ostatnim wydanym.

Uwaga

Możesz użyć use w wyrażeniach obliczeniowych, w tym przypadku jest używana niestandardowa wersja use wyrażenia. Aby uzyskać więcej informacji, zobacz Sekwencje, Wyrażenia asynchroniczne, Wyrażenia zadań i Wyrażenia obliczeniowe.

przy użyciu funkcji

Funkcja using ma następującą formę:

using (expression1) function-or-lambda

W wyrażeniu using wyrażenie1 tworzy obiekt, który musi zostać usunięty. Wynik wyrażenia1 (obiekt, który musi zostać usunięty) staje się argumentem, wartością funkcji lub lambda, która jest funkcją, która oczekuje pojedynczego pozostałego argumentu typu zgodnego z wartością wygenerowaną przez wyrażenie1 lub wyrażenie lambda, które oczekuje argumentu tego typu. Na końcu wykonywania funkcji środowisko uruchomieniowe wywołuje Dispose i zwalnia zasoby (chyba że wartość to null, w tym przypadku wywołanie metody Dispose nie zostanie podjęta).

W poniższym przykładzie pokazano using wyrażenie z wyrażeniem lambda.

open System.IO

let writetofile2 filename obj =
    using (System.IO.File.CreateText(filename)) ( fun file1 ->
        file1.WriteLine("{0}", obj.ToString() )
    )

writetofile2 "abc2.txt" "The quick sly fox jumps over the lazy brown dog."

W następnym przykładzie pokazano using wyrażenie z funkcją.

let printToFile (file1 : System.IO.StreamWriter) =
    file1.WriteLine("Test output");

using (System.IO.File.CreateText("test.txt")) printToFile

Należy pamiętać, że funkcja może być funkcją, która ma już zastosowane argumenty. W poniższym przykładzie kodu pokazano to. Tworzy plik zawierający ciąg XYZ.

let printToFile2 obj (file1 : System.IO.StreamWriter) =
    file1.WriteLine(obj.ToString())

using (System.IO.File.CreateText("test.txt")) (printToFile2 "XYZ")

Funkcja using i use powiązanie są niemal równoważnymi sposobami wykonania tej samej czynności. Słowo using kluczowe zapewnia większą kontrolę nad wywołaniami Dispose . Gdy używasz elementu , Dispose jest wywoływany na końcu wyrażenia funkcji lub lambda. Gdy używasz usinguse słowa kluczowego, Dispose jest wywoływany na końcu zawierającego blok kodu. Ogólnie rzecz biorąc, należy użyć funkcji use zamiast using funkcji.

Zobacz też