Utilisation d’objets implémentant IDisposableUsing objects that implement IDisposable
Le récupérateur de mémoire du Common Language Runtime libère la mémoire utilisée par les objets managés, mais les types qui utilisent des ressources non managées implémentent l'interface IDisposable pour permettre à la mémoire allouée à ces ressources non managées d'être récupérée.The common language runtime's garbage collector reclaims the memory used by managed objects, but types that use unmanaged resources implement the IDisposable interface to allow the memory allocated to these unmanaged resources to be reclaimed. Une fois que vous avez fini d'utiliser un objet qui implémente IDisposable, vous devez appeler l'implémentation de IDisposable.Dispose de l'objet.When you finish using an object that implements IDisposable, you should call the object's IDisposable.Dispose implementation. Vous pouvez le faire de deux façons :You can do this in one of two ways:
Avec l’instruction
using
C# ou l’instructionUsing
Visual Basic.With the C#using
statement or the Visual BasicUsing
statement.En implémentant un bloc
try/finally
.By implementing atry/finally
block.
Instruction usingThe using statement
L’instruction using
en C# et l’instruction Using
en Visual Basic simplifient le code que vous devez écrire pour créer et nettoyer un objet.The using
statement in C# and the Using
statement in Visual Basic simplify the code that you must write to create and clean up an object. L’instruction using
obtient une ou plusieurs ressources, exécute les instructions que vous spécifiez, puis supprime automatiquement l’objet.The using
statement obtains one or more resources, executes the statements that you specify, and automatically disposes of the object. Toutefois, l’instruction using
est utile uniquement pour les objets utilisés dans la portée de la méthode dans laquelle elles sont construites.However, the using
statement is useful only for objects that are used within the scope of the method in which they are constructed.
L’exemple suivant utilise l’instruction using
pour créer et libérer un objet System.IO.StreamReader.The following example uses the using
statement to create and release a System.IO.StreamReader object.
using System;
using System.IO;
public class Example
{
public static void Main()
{
Char[] buffer = new Char[50];
using (StreamReader s = new StreamReader("File1.txt")) {
int charsRead = 0;
while (s.Peek() != -1) {
charsRead = s.Read(buffer, 0, buffer.Length);
//
// Process characters read.
//
}
}
}
}
Imports System.IO
Module Example
Public Sub Main()
Dim buffer(49) As Char
Using s As New StreamReader("File1.txt")
Dim charsRead As Integer
Do While s.Peek() <> -1
charsRead = s.Read(buffer, 0, buffer.Length)
'
' Process characters read.
'
Loop
End Using
End Sub
End Module
Notez que, bien que la classe StreamReader implémente l'interface IDisposable, ce qui signifie qu'elle utilise une ressource non managée, l'exemple n'appelle pas explicitement la méthode StreamReader.Dispose.Note that although the StreamReader class implements the IDisposable interface, which indicates that it uses an unmanaged resource, the example doesn't explicitly call the StreamReader.Dispose method. Quand le compilateur C# ou Visual Basic rencontre l’instruction using
, il émet en langage intermédiaire qui est équivalent au code suivant contenant explicitement un bloc try/finally
.When the C# or Visual Basic compiler encounters the using
statement, it emits intermediate language (IL) that is equivalent to the following code that explicitly contains a try/finally
block.
using System;
using System.IO;
public class Example
{
public static void Main()
{
Char[] buffer = new Char[50];
{
StreamReader s = new StreamReader("File1.txt");
try {
int charsRead = 0;
while (s.Peek() != -1) {
charsRead = s.Read(buffer, 0, buffer.Length);
//
// Process characters read.
//
}
}
finally {
if (s != null)
((IDisposable)s).Dispose();
}
}
}
}
Imports System.IO
Module Example
Public Sub Main()
Dim buffer(49) As Char
'' Dim s As New StreamReader("File1.txt")
With s As New StreamReader("File1.txt")
Try
Dim charsRead As Integer
Do While s.Peek() <> -1
charsRead = s.Read(buffer, 0, buffer.Length)
'
' Process characters read.
'
Loop
Finally
If s IsNot Nothing Then DirectCast(s, IDisposable).Dispose()
End Try
End With
End Sub
End Module
L’instruction using
en C# vous permet d’acquérir plusieurs ressources dans une seule instruction, ce qui équivaut en interne à des instructions using
imbriquées.The C# using
statement also allows you to acquire multiple resources in a single statement, which is internally equivalent to nested using
statements. L'exemple suivant instancie deux objets StreamReader pour lire le contenu de deux fichiers différents.The following example instantiates two StreamReader objects to read the contents of two different files.
using System;
using System.IO;
public class Example
{
public static void Main()
{
Char[] buffer1 = new Char[50], buffer2 = new Char[50];
using (StreamReader version1 = new StreamReader("file1.txt"),
version2 = new StreamReader("file2.txt")) {
int charsRead1, charsRead2 = 0;
while (version1.Peek() != -1 && version2.Peek() != -1) {
charsRead1 = version1.Read(buffer1, 0, buffer1.Length);
charsRead2 = version2.Read(buffer2, 0, buffer2.Length);
//
// Process characters read.
//
}
}
}
}
Bloc try/finallyTry/finally block
Au lieu d’encapsuler un bloc try/finally
dans une instruction using
, vous pouvez choisir d’implémenter le bloc try/finally
directement.Instead of wrapping a try/finally
block in a using
statement, you may choose to implement the try/finally
block directly. Il peut s'agir de votre style personnel en matière de codage, ou vous pouvez procéder ainsi pour l'une des raisons suivantes :This may be your personal coding style, or you might want to do this for one of the following reasons:
Pour insérer un bloc
catch
afin de gérer toutes les exceptions levées dans le bloctry
.To include acatch
block to handle any exceptions thrown in thetry
block. Sinon, toutes les exceptions levées par l’instructionusing
ne sont pas gérées, de même que toutes les exceptions levées dans le blocusing
si un bloctry/catch
n’est pas présent.Otherwise, any exceptions thrown by theusing
statement are unhandled, as are any exceptions thrown within theusing
block if atry/catch
block isn't present.Pour instancier un objet qui implémente IDisposable dont la portée n'est pas locale au bloc dans lequel elle est déclarée.To instantiate an object that implements IDisposable whose scope is not local to the block within which it is declared.
L'exemple suivant est similaire à l'exemple précédent, mais il utilise un bloc try/catch/finally
pour instancier, utiliser et supprimer un objet StreamReader, ainsi que pour gérer les exceptions levées par le constructeur StreamReader et sa méthode ReadToEnd.The following example is similar to the previous example, except that it uses a try/catch/finally
block to instantiate, use, and dispose of a StreamReader object, and to handle any exceptions thrown by the StreamReader constructor and its ReadToEnd method. Notez que le code du bloc finally
vérifie que l'objet qui implémente IDisposable n'est pas null
avant d'appeler la méthode Dispose.Note that the code in the finally
block checks that the object that implements IDisposable isn't null
before it calls the Dispose method. La non-exécution de cette opération peut générer une NullReferenceException au moment de l'exécution.Failure to do this can result in a NullReferenceException exception at run time.
using System;
using System.Globalization;
using System.IO;
public class Example
{
public static void Main()
{
StreamReader sr = null;
try {
sr = new StreamReader("file1.txt");
String contents = sr.ReadToEnd();
Console.WriteLine("The file has {0} text elements.",
new StringInfo(contents).LengthInTextElements);
}
catch (FileNotFoundException) {
Console.WriteLine("The file cannot be found.");
}
catch (IOException) {
Console.WriteLine("An I/O error has occurred.");
}
catch (OutOfMemoryException) {
Console.WriteLine("There is insufficient memory to read the file.");
}
finally {
if (sr != null) sr.Dispose();
}
}
}
Imports System.Globalization
Imports System.IO
Module Example
Public Sub Main()
Dim sr As StreamReader = Nothing
Try
sr = New StreamReader("file1.txt")
Dim contents As String = sr.ReadToEnd()
Console.WriteLine("The file has {0} text elements.",
New StringInfo(contents).LengthInTextElements)
Catch e As FileNotFoundException
Console.WriteLine("The file cannot be found.")
Catch e As IOException
Console.WriteLine("An I/O error has occurred.")
Catch e As OutOfMemoryException
Console.WriteLine("There is insufficient memory to read the file.")
Finally
If sr IsNot Nothing Then sr.Dispose()
End Try
End Sub
End Module
Vous pouvez suivre ce modèle de base si vous choisissez d’implémenter (ou que vous devez implémenter) un bloc try/finally
, car votre langage de programmation ne prend pas en charge l’instruction using
, mais autorise des appels directs à la méthode Dispose.You can follow this basic pattern if you choose to implement or must implement a try/finally
block, because your programming language doesn't support a using
statement but does allow direct calls to the Dispose method.
Voir aussiSee also
Commentaires
Chargement du commentaire...