Gestion des ressources : mot clé « use » (F#)
Cette rubrique décrit le mot clé use et la fonction using, qui peuvent contrôler l'initialisation et la libération de ressources.
Ressources
Le terme ressource a plusieurs significations. Il désigne bien entendu les données qui sont utilisées par une application, par exemple des chaînes, des graphiques, etc. Toutefois, dans ce contexte, le terme ressource fait référence aux ressources logicielles ou du système d'exploitation, par exemple les contextes de périphérique graphique, les handles de fichiers, les connexions réseau et de base de données, les objets d'accès concurrentiel comme les handles d'attente, etc. L'utilisation de ces ressources par les applications implique l'acquisition de la ressource auprès du système d'exploitation ou d'un autre fournisseur de ressources, puis la libération de la ressource dans le pool afin qu'elle puisse être fournie à une autre application. Des problèmes se produisent lorsque des applications ne libèrent pas les ressources dans le pool commun.
Gestion des ressources
Pour gérer efficacement et de manière responsable les ressources dans une application, vous devez libérer les ressources rapidement et de façon prévisible. Le .NET Framework vous aide dans cette tâche au moyen de l'interface IDisposable. Un type qui implémente IDisposable a la méthode Dispose, qui libère correctement les ressources. Des applications bien écrites garantissent que Dispose est appelé rapidement lorsqu'un objet qui contient une ressource limitée n'est plus nécessaire. Heureusement, la plupart des langages .NET, dont F#, proposent des solutions pour vous faciliter la tâche. Deux constructions de langage utiles prennent en charge le modèle de suppression : la liaison use et la fonction using.
Liaison use
Le mot clé use a une forme semblable à celle de la liaison let :
use value = expression
Il fournit la même fonctionnalité qu'une liaison let, mais ajoute un appel à Dispose sur la valeur lorsque la valeur est hors de portée. Notez que le compilateur insère un contrôle de valeur Null sur la valeur, afin que si la valeur est null, l'appel à Dispose ne soit pas tenté.
L'exemple suivant montre comment fermer automatiquement un fichier à l'aide du mot clé 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."
Notes
Vous pouvez utiliser use dans les expressions de calcul, auquel cas une version personnalisée de l'expression use est utilisée.Pour plus d'informations, consultez Séquences (F#), Workflows asynchrones (F#) et Expressions de calcul (F#).
Fonction using
La fonction using se présente sous la forme suivante :
using (expression1) function-or-lambda
Dans une expression using, expression1 crée l'objet à supprimer. Le résultat d'expression1 (objet à supprimer) devient un argument, value, à function-or-lambda, qui est soit une fonction qui attend un argument restant unique d'un type qui correspond à la valeur produite par expression1, soit une expression lambda qui attend un argument de ce type. À la fin de l'exécution de la fonction, l'exécution appelle Dispose et libère les ressources (à moins que la valeur ne soit null, auquel cas l'appel à Dispose n'est pas tenté).
L'exemple suivant montre l'expression using avec une expression 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 jumped over the lazy brown dog."
L'exemple suivant montre l'expression using avec une fonction.
let printToFile (file1 : System.IO.StreamWriter) =
file1.WriteLine("Test output");
using (System.IO.File.CreateText("test.txt")) printToFile
Notez que la fonction peut être une fonction avec des arguments déjà appliqués. L'exemple de code suivant illustre ceci. Elle crée un fichier qui contient la chaîne XYZ.
let printToFile2 obj (file1 : System.IO.StreamWriter) =
file1.WriteLine(obj.ToString())
using (System.IO.File.CreateText("test.txt")) (printToFile2 "XYZ")
La fonction using et la liaison use parviennent au même résultat de façon presque équivalente. Le mot clé using offre plus de contrôle lorsque Dispose est appelé. Lorsque vous utilisez using, Dispose est appelé à la fin de la fonction ou de l'expression lambda ; lorsque vous utilisez le mot clé use, Dispose est appelé à la fin du bloc de code contenant. En général, préférez utiliser use plutôt que la fonction using.