Partager via


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.

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.

See also