Gestion des ressources : mot clé « use »
Cette rubrique décrit le mot clé use
et la fonction using
, qui peut contrôler l’initialisation et la libération des ressources.
Ressources
Le terme ressource est utilisé de plusieurs façons. Oui, les ressources peuvent être des données qu’une application utilise, comme des chaînes, des graphiques, etc., mais dans ce contexte, les ressources font référence à des ressources logicielles ou de système d’exploitation, comme des contextes de périphériques graphiques, des descripteurs de fichiers, des connexions réseau et de base de données, des objets de concurrence, comme des descripteurs 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, suivie de la publication ultérieure de la ressource dans le pool afin qu’elle puisse être fournie à une autre application. Des problèmes se produisent lorsque les 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 manière prévisible. .NET Framework vous aide à le faire en fournissant l’interface System.IDisposable
. Un type qui implémente System.IDisposable
a la méthode System.IDisposable.Dispose
, qui libère correctement les ressources. Les applications bien écrites garantissent que System.IDisposable.Dispose
est appelé rapidement lorsqu’un objet qui contient une ressource limitée n’est plus nécessaire. Heureusement, la plupart des langages .NET prennent cela en charge pour faciliter cette tâche, et F# ne fait pas exception. Il existe deux constructions de langage utiles qui prennent en charge le modèle Dispose : la liaison use
et la fonction using
.
Utiliser la liaison
Le mot clé use
a une forme semblable à celle de la liaison let
:
use valeur = expression
Il fournit les mêmes fonctionnalités qu’une liaison let
, mais ajoute un appel à Dispose
sur la valeur lorsque la valeur sort de l’étendue. Notez que le compilateur insère une vérification null sur la valeur, de sorte que si la valeur est null
, l’appel à Dispose
n’est pas tenté.
L’exemple suivant montre comment fermer un fichier automatiquement à 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."
Plusieurs instances de use
sont supprimées dans l’ordre inverse dans lequel elles sont déclarées. Autrement dit, la première use
sera la dernière mise en production.
Remarque
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, Expressions asynchrones, Expressions de tâche et Expressions de calcul.
Fonction using
La fonction using
a la forme suivante :
using
(expression1) fonction-ou-lambda
Dans une expression using
, expression1 crée l’objet qui doit être supprimé. Le résultat d’expression1 (l’objet qui doit être supprimé) devient un argument, valeur, pour fonction-ou-lambda, qui est soit une fonction qui attend un seul argument restant 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, le runtime appelle Dispose
et libère les ressources (sauf si la valeur est null
, auquel cas l’appel à Dispose n’est pas tenté).
L’exemple suivant illustre 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 jumps 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 cette tâche. Cela 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
sont des façons presque équivalentes d’accomplir la même chose. Le mot clé using
offre davantage de contrôle sur le moment où 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
.