Gestione di risorse: parola chiave use

Questo argomento descrive la parola chiave use e la using funzione , che può controllare l'inizializzazione e il rilascio delle risorse.

Risorse

Il termine risorsa viene usato in più modi. Sì, le risorse possono essere dati usati da un'applicazione, ad esempio stringhe, grafica e simili, ma in questo contesto le risorse fanno riferimento a risorse software o del sistema operativo, ad esempio contesti di dispositivo grafico, handle di file, connessioni di rete e database, oggetti di concorrenza come handle di attesa e così via. L'uso di queste risorse da parte delle applicazioni comporta l'acquisizione della risorsa dal sistema operativo o da un altro provider di risorse, seguita dalla versione successiva della risorsa nel pool in modo che possa essere fornita a un'altra applicazione. I problemi si verificano quando le applicazioni non rilasciano risorse nel pool comune.

Gestione delle risorse

Per gestire in modo efficiente e responsabile le risorse in un'applicazione, è necessario rilasciare le risorse tempestivamente e in modo prevedibile. .NET Framework consente di eseguire questa operazione fornendo l'interfaccia System.IDisposable . Un tipo che implementa System.IDisposable ha il System.IDisposable.Dispose metodo , che libera correttamente le risorse. Le applicazioni ben scritte garantiscono che System.IDisposable.Dispose venga chiamato tempestivamente quando qualsiasi oggetto che contiene una risorsa limitata non è più necessario. Fortunatamente, la maggior parte dei linguaggi .NET offre supporto per semplificare questa operazione e F# non fa eccezione. Esistono due costrutti di linguaggio utili che supportano il modello dispose: l'associazione use e la using funzione.

usare binding

La use parola chiave ha un formato simile a quello dell'associazione let :

usare un'espressione di valore =

Fornisce la stessa funzionalità di un'associazione let , ma aggiunge una chiamata a Dispose sul valore quando il valore esce dall'ambito. Si noti che il compilatore inserisce un controllo Null sul valore, in modo che se il valore è null, la chiamata a Dispose non viene tentata.

Nell'esempio seguente viene illustrato come chiudere automaticamente un file usando la use parola chiave .

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

Più istanze di use vengono eliminate nell'ordine inverso in cui vengono dichiarate. Ovvero, il primo use sarà l'ultimo rilasciato.

Nota

È possibile usare use nelle espressioni di calcolo, nel qual caso viene usata una versione personalizzata dell'espressione use . Per altre informazioni, vedere Sequenze, espressioni asincrone, espressioni task ed espressioni di calcolo.

using Function

La using funzione ha il formato seguente:

using (expression1) function-or-lambda

In un'espressione using expression expression1 crea l'oggetto che deve essere eliminato. Il risultato di expression1 (l'oggetto che deve essere eliminato) diventa un argomento, un valore, per function-or-lambda, che è una funzione che prevede un singolo argomento rimanente di un tipo che corrisponde al valore generato da expression1 o un'espressione lambda che prevede un argomento di tale tipo. Alla fine dell'esecuzione della funzione, il runtime chiama Dispose e libera le risorse (a meno che il valore non sia null, nel qual caso la chiamata a Dispose non viene tentata).

Nell'esempio seguente viene illustrata l'espressione con un'espressione using 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."

Nell'esempio seguente viene illustrata l'espressione using con una funzione .

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

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

Si noti che la funzione potrebbe essere una funzione con alcuni argomenti già applicati. Nell'esempio di codice seguente viene illustrata questa possibilità. Crea un file contenente la stringa XYZ.

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

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

La using funzione e l'associazione use sono quasi equivalenti per eseguire la stessa operazione. La using parola chiave fornisce un maggiore controllo su quando Dispose viene chiamato . Quando si usa using, Dispose viene chiamato alla fine della funzione o dell'espressione lambda. Quando si usa la use parola chiave , Dispose viene chiamato alla fine del blocco di codice contenitore. In generale, è consigliabile usare use anziché la using funzione .

Vedi anche