Dispose pattern
This article needs additional citations for verification. (February 2013) |
In computer programming, the dispose pattern is a design pattern which is used to handle resource cleanup and prevent resource leaks in runtime environments that use automatic garbage collection. The fundamental problem that the dispose pattern aims to solve is that, because objects in a garbage-collected environment have finalizers rather than destructors, there is no guarantee that an object will be destroyed at any deterministic point in time. The dispose pattern works around this by giving an object a method (usually called Dispose
or similar) which frees any resources the object is holding onto.
Many garbage-collected languages offer language constructs to avoid having to call the dispose method explicitly in many situations. These language constructs leads to results similar to what is obtained with the Resource Acquisition Is Initialization (RAII) idiom in languages with deterministic memory management (e.g. C++).
Motivation
It is very common to write code similar to the listing below when using resources that might throw exceptions in garbage-collected languages:
Resource resource = null;
try {
// Attempt to acquire the resource.
resource = getResource();
// Perform actions with the resource.
...
} finally {
// Resource might not have been acquired, or already freed
if (resource != null)
resource.dispose();
}
The try...finally
construct is necessary for proper exception safety, since the finally
block enables execution of cleanup logic regardless of if an exception is thrown or not in the try
block.
One disadvantage of this approach is that it requires the programmer to explicitly add cleanup code in a finally
block. This leads to code size bloat, and failure to do so will lead to resource leakage in the program.
Language constructs
To make the dispose pattern less verbose, several languages have some kind of built-in support for resources held and released in the same block of code.
The C# language features the using
statement [1] that automatically calls the Dispose
method on an object that implements the IDisposable
interface:
using (Resource resource = GetResource())
{
// Perform actions with the resource.
...
}
which is equal to:
Resource resource = GetResource()
try
{
// Perform actions with the resource.
...
}
finally
{
// Resource might not been acquired, or already freed
if (resource != null)
((IDisposable)resource).Dispose();
}
Similarly, the Python language has a with
statement that can be used to similar effect with a context manager object. The context manager protocol requires implementing __enter__
and __exit__
methods which get automatically called by the with
statement construct, to prevent duplication of code that would otherwise occur with the try
/finally
pattern.[2]
with resource_context_manager() as resource:
# Perform actions with the resource.
...
# Perform other actions where the resource is guaranteed to be deallocated.
...
The Java language introduced a new syntax called try
-with-resources in Java version 7.[3] It can be used on objects that implement the AutoCloseable interface (that defines method close()):
try ( OutputStream x = new OutputStream(...) ){
//do something with x
} catch(IOException ex){
//handle exception
// The resource x is automatically closed
} // try
See also
References
- ^ Microsoft MSDN: using Statement (C# Reference)
- ^ Guido van Rossum, Nick Coghlan (13 June 2011). "PEP 343: The "with" Statement". Python Software Foundation.
- ^ Oracle Java tutorial: The try-with-resources Statement