Resourcebeheer: het gebruik van trefwoord

In dit onderwerp worden het trefwoord use en de using functie beschreven, waarmee u de initialisatie en release van resources kunt beheren.

Resources

De termresource wordt op meer dan één manier gebruikt. Ja, resources kunnen gegevens zijn die een toepassing gebruikt, zoals tekenreeksen, afbeeldingen en dergelijke, maar in deze context verwijzen resources naar software- of besturingssysteembronnen, zoals contexten van grafische apparaten, bestandsingangen, netwerk- en databaseverbindingen, gelijktijdigheidsobjecten zoals wachtgrepen, enzovoort. Het gebruik van deze resources door toepassingen omvat de verwerving van de resource van het besturingssysteem of een andere resourceprovider, gevolgd door de latere release van de resource in de pool, zodat deze aan een andere toepassing kan worden verstrekt. Er treden problemen op wanneer toepassingen geen resources vrijgeven aan de gemeenschappelijke pool.

Resources beheren

Als u resources in een toepassing efficiënt en verantwoord wilt beheren, moet u resources onmiddellijk en op een voorspelbare manier vrijgeven. Het .NET Framework helpt u dit te doen door de System.IDisposable interface te bieden. Een type dat wordt geïmplementeerd System.IDisposable , heeft de System.IDisposable.Dispose methode, waarmee resources correct worden vrijgemaakt. Goed geschreven toepassingen garanderen dat deze System.IDisposable.Dispose onmiddellijk worden aangeroepen wanneer een object dat een beperkte resource bevat niet meer nodig is. Gelukkig bieden de meeste .NET-talen ondersteuning om dit eenvoudiger te maken, en F# is geen uitzondering. Er zijn twee nuttige taalconstructies die ondersteuning bieden voor het verwijderingspatroon: de use binding en de using functie.

Binding gebruiken

Het use trefwoord heeft een formulier dat lijkt op die van de let binding:

waarde-expressie = gebruiken

Het biedt dezelfde functionaliteit als een let binding, maar voegt een aanroep toe aan Dispose de waarde wanneer de waarde buiten het bereik valt. Houd er rekening mee dat de compiler een null-controle op de waarde invoegt, zodat de aanroep naar Dispose de waarde niet wordt geprobeerd als de waarde isnull.

In het volgende voorbeeld ziet u hoe u een bestand automatisch sluit met behulp van het use trefwoord.

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."

Meerdere exemplaren worden use verwijderd in de omgekeerde volgorde waarin ze worden gedeclareerd. Dat wil gezegd, de eerste use zal de laatste zijn die is uitgebracht.

Notitie

U kunt in berekeningsexpressies gebruiken use . In dat geval wordt een aangepaste versie van de use expressie gebruikt. Zie Reeksen, Asynchrone expressies, taakexpressies en rekenexpressies voor meer informatie.

functie gebruiken

De using functie heeft de volgende vorm:

using (expression1) functie-of-lambda

In een using expressie maakt expression1 het object dat moet worden verwijderd. Het resultaat van expressie1 (het object dat moet worden verwijderd) wordt een argument, waarde, functie-of-lambda. Dit is een functie die één resterend argument verwacht van een type dat overeenkomt met de waarde die is geproduceerd door expressie1, of een lambda-expressie die een argument van dat type verwacht. Aan het einde van de uitvoering van de functie worden de resources door de runtime aangeroepen Dispose en vrijgemaakt (tenzij de waarde is null, in welk geval de aanroep om te verwijderen niet wordt geprobeerd).

In het volgende voorbeeld ziet u de using expressie met een lambda-expressie.

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."

In het volgende voorbeeld ziet u de using expressie met een functie.

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

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

Houd er rekening mee dat de functie een functie kan zijn waarop al enkele argumenten zijn toegepast. In het volgende codevoorbeeld ziet u dit. Er wordt een bestand gemaakt dat de tekenreeks XYZbevat.

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

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

De using functie en de use binding zijn bijna gelijkwaardige manieren om hetzelfde te bereiken. Het using trefwoord biedt meer controle over wanneer Dispose wordt aangeroepen. Wanneer u dit gebruikt using, Dispose wordt aangeroepen aan het einde van de functie- of lambda-expressie. Wanneer u het use trefwoord gebruikt, Dispose wordt aangeroepen aan het einde van het codeblok. Over het algemeen moet u liever in plaats van de using functie gebruikenuse.

Zie ook