How effectively release memory of unmanaged resource in .NET? - ablealias/asp.net GitHub Wiki
The common language runtime's (CLR) 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. When you finish using an object that implements IDisposable, you should call the object's IDisposable.Dispose implementation. You can do this in one of two ways:
- With the C# using statement.
- By implementing a try/finally block.
The using statement
The using
statement in C# simplify the code that you must write to create and clean up an object. The using
statement obtains one or more resources, executes the statements that you specify, and automatically disposes
of the object. However, the using
statement is useful only for objects that are used within the scope of the method in which they are constructed.
When the lifetime of an IDisposable
object is limited to a single method, you should declare and instantiate it in a using
statement. The using
statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using
block, the object is read-only and cannot be modified or reassigned.
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.
//
}
s.Close();
}
}
}
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. When the C# compiler encounters the using
statement, it emits intermediate language (IL) that is equivalent to the code that explicitly contains a try/finally
block.
The C# using
statement also allows you to acquire multiple resources
in a single statement, which is internally equivalent to nested using
statements. 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.
//
}
version1.Close();
version2.Close();
}
}
}