CA2202: Do not dispose objects multiple times
Item | Value |
---|---|
RuleId | CA2202 |
Category | Microsoft.Usage |
Breaking change | Non-breaking |
Cause
A method implementation contains code paths that could cause multiple calls to System.IDisposable.Dispose or a Dispose equivalent, such as a Close() method on some types, on the same object.
Note
This rule has been deprecated. For more information, see Deprecated rules.
Rule description
A correctly implemented Dispose method can be called multiple times without throwing an exception. However, this is not guaranteed and to avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.
Related rules
How to fix violations
To fix a violation of this rule, change the implementation so that regardless of the code path, Dispose is called only one time for the object.
When to suppress warnings
Do not suppress a warning from this rule. Even if Dispose for the object is known to be safely callable multiple times, the implementation might change in the future.
Example 1
Nested using
statements (Using
in Visual Basic) can cause violations of the CA2202 warning. If the IDisposable resource of the nested inner using
statement contains the resource of the outer using
statement, the Dispose
method of the nested resource releases the contained resource. When this situation occurs, the Dispose
method of the outer using
statement attempts to dispose its resource for a second time.
In the following example, a Stream object that is created in an outer using statement is released at the end of the inner using statement in the Dispose method of the StreamWriter object that contains the stream
object. At the end of the outer using
statement, the stream
object is released a second time. The second release is a violation of CA2202.
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}
}
Example 2
To resolve this issue, use a try
/finally
block instead of the outer using
statement. In the finally
block, make sure that the stream
resource is not null.
Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
stream?.Dispose();
}
Tip
The ?.
syntax above is the null-conditional operator.