Click to Rate and Give Feedback
Collapse All/Expand All Collapse All
This page is specific to
Microsoft Visual Studio 2010/.NET Framework 4

Other versions are also available for the following:
CA2000: Dispose objects before losing scope

TypeName

DisposeObjectsBeforeLosingScope

CheckId

CA2000

Category

Microsoft.Reliability

Breaking Change

Non-breaking

A local object of a IDisposable type is created but the object is not disposed before all references to the object are out of scope.

If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.

To fix a violation of this rule, call Dispose on the object before all references to it are out of scope.

Note that you can use the using statement (Using in Visual Basic) to wrap objects that implement IDisposable. Objects that are wrapped in this manner will automatically be disposed at the close of the using block.

The following are some situations where the using statement is not enough to protect IDisposable objects and can cause CA2000 to occur.

  • Returning a disposable object requires that the object is constructed in a try/finally block outside a using block.

  • Initializing members of a disposable object should not be done in the constructor of a using statement.

  • Nesting constructors that are protected only by one exception handler. For example,

    using (StreamReader sr = new StreamReader(new FileStream("C:\myfile.txt", FileMode.Create)))
    { ... }

    causes CA2000 to occur because a failure in the construction of the StreamReader object can result in the FileStream object never being closed.

  • Dynamic objects should use a shadow object to implement the Dispose pattern of IDisposable objects.

Do not suppress a warning from this rule unless you have called a method on your object that calls Dispose, such as Close.

If you are implementing a method that returns a disposable object, use a try/finally block without a catch block to make sure that the object is disposed. By using a try/finally block, you allow exceptions to be raised at the fault point and make sure that object is disposed.

In the OpenPort1 method, the call to open the ISerializable object SerialPort or the call to SomeMethod can fail. A CA2000 warning is raised on this implementation.

In the OpenPort2 method, two SerialPort objects are declared and set to null:

  • tempPort, which is used to test that the method operations succeed.

  • port, which is used for the return value of the method.

The tempPort is constructed and opened in a try block, and any other required work is performed in the same try block. At the end of the try block, the opened port is assigned to the port object that will be returned and the tempPort object is set to null.

The finally block checks the value of tempPort. If it is not null, an operation in the method has failed, and tempPort is closed to make sure that any resources are released. The returned port object will contain the opened SerialPort object if the operations of the method succeeded, or it will be null if an operation failed.

Visual Basic
Public Function OpenPort1(ByVal PortName As String) As SerialPort

   Dim port As New SerialPort(PortName)
   port.Open()    'CA2000 fires because this might throw
   SomeMethod()   'Other method operations can fail
   Return port

End Function


Public Function OpenPort2(ByVal PortName As String) As SerialPort

   Dim tempPort As SerialPort = Nothing
   Dim port As SerialPort = Nothing

   Try
      tempPort = New SerialPort(PortName)
      tempPort.Open()
      SomeMethod()
      'Add any other methods above this line
      port = tempPort
      tempPort = Nothing

   Finally
      If Not tempPort Is Nothing Then
         tempPort.Close()
      End If


   End Try

   Return port

End Function

Visual Basic
Public Function CreateReader1(ByVal x As Integer) As StreamReader
   Dim local As New StreamReader("C:\Temp.txt")
   x += 1
   Return local
End Function


Public Function CreateReader2(ByVal x As Integer) As StreamReader
   Dim local As StreamReader = Nothing
   Dim localTemp As StreamReader = Nothing
   Try
      localTemp = New StreamReader("C:\Temp.txt")
      x += 1
      local = localTemp
      localTemp = Nothing
      Finally
         If (Not (localTemp Is Nothing)) Then
            localTemp.Dispose()
         End If
   End Try
   Return local
End Function
C#

public SerialPort OpenPort1(string portName)
{
   SerialPort port = new SerialPort(portName);
   port.Open();  //CA2000 fires because this might throw
   SomeMethod(); //Other method operations can fail
   return port;
}

public SerialPort OpenPort2(string portName)
{
   SerialPort tempPort = null;
   SerialPort port = null;
   try
   {
      tempPort = new SerialPort(portName);
      tempPort.Open();
      SomeMethod();
      //Add any other methods above this line
      port = tempPort;
      tempPort = null;

   }
   finally
   {
      if (tempPort != null)
      {
         tempPort.Close();
      }
   }
   return port;
}

By default, the Visual Basic compiler has all arithmetic operators check for overflow. Therefore, any Visual Basic arithmetic operation might throw an OverflowException. This could lead to unexpected violations in rules such as CA2000. For example, the following CreateReader1 function will produce a CA2000 violation because the Visual Basic compiler is emitting an overflow checking instruction for the addition that could throw an exception that would cause the StreamReader not to be disposed.

To fix this, you can disable the emitting of overflow checks by the Visual Basic compiler in your project or you can modify your code as in the following CreateReader2 function.

To disable the emitting of overflow checks, right-click the project name in Solution Explorer and then click Properties. Click Compile, click Advanced Compile Options, and then check Remove integer overflow checks.

Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
How to suppress this - if you have a justification :)      aephid technologies   |   Edit   |   Show History
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability",

"CA2000:DisposeObjectsBeforeLosingScope")]

Tags What's this?: Add a tag
Flag as ContentBug
Doesn't make sense to me.      Brent Rockwood   |   Edit   |   Show History
In the sample OpenPort2, presumably one is returning the port object so that the caller can use it for something, but at that point it is disposed. I cannot see how this is a useful idiom for instances when one wishes to return a disposable object.$0 $0$0 $0$0 $0$0
Tags What's this?: Add a tag
Flag as ContentBug
Instance variable created with an object initializer      T.T.Hayes   |   Edit   |   Show History
I get the same problem as Martin Hudasch mentioned, except in my case it's an instance variable, not a local variable. I am using an object initializer for it, though. Not using an object initializer seems to fix it, but my code shouldn't be dictated by bugs in Code Analysis.
Tags What's this?: Add a tag
Flag as ContentBug
It also is sometimes triggered by initializers      Locarno   |   Edit   |   Show History
It also is sometimes triggered by initializers, even though the "temp local variable" is supposed to be abstracted away.  See http://stackoverflow.com/questions/4663693/why-am-i-getting-ca2000-with-a-private-member-idisposable-inside-my-idisposable-c
Tags What's this?: Add a tag
Flag as ContentBug
Disagreeing with Code Analysis Rules      Patrick Sheahan   |   Edit   |   Show History
Hi,
The MSDN Library community content is designed primarily to enable MSDN users to provide feedback, extensions and explanations of the documentation. It is not a good way to have issues with the code analysis rules themselves addressed. To discuss the implementation of code analysis rules, post your questions or opinions on the Visual Studio Code Analysis and Code Metrics forum (http://social.msdn.microsoft.com/Forums/en-US/vstscode/). To provide feedback directly to the development team, you can file a bug on the Connect site for Visual Studio 2010 and .NET Framework 4 (https://connect.microsoft.com/VisualStudio). The dev team encourages your feedback through these channels.
Tags What's this?: Add a tag
Flag as ContentBug
Show Form...      Matias Toro   |   Edit   |   Show History

In my case, I have to show a winform. For that I'm calling to "Show" method from "Form" class. The violation rule occurs when I'm calling the show method.
My code snippet is it:

MyForm form = null;
try
{
form = new MyForm();
form.Show();
form = null;
}
finally
{
if( form != null &;;&;; !form.IsDisposed )
{
form.Dispose();
}
}

So, I can't use "using" because when the form is out of scope this one would be close. I need to know how to do to show a form no modal and it rule never broken.$0 $0Anybody help me with that? Let me know of anybody need more information about that.

Regards

Tags What's this?: Add a tag
Flag as ContentBug
CA2000 When reference is passed to constructor of another object that does not go out of scope      Rich Collette   |   Edit   |   Show History
CA2000 is still flagged when a reference is passed in the constructor of another object and that other object does not go out of scope. See the following code example.

Public Shared ReadOnly Property Current() As HttpSessionState
Get
If (HttpContext.Current Is Nothing) Then
Dim writer As System.IO.StringWriter = Nothing
Try
writer = New System.IO.StringWriter(CultureInfo.InvariantCulture)
HttpContext.Current = New HttpContext(New HttpRequest("", "http://localhost/", ""), New HttpResponse(writer))
SessionStateUtility.AddHttpSessionStateToContext(HttpContext.Current, New HttpSessionStateContainer("", New SessionStateItemCollection(),New HttpStaticObjectsCollection(), 20000, True, HttpCookieMode.UseCookies, SessionStateMode.Off, False))
Catch
If writer IsNot Nothing Then writer.Dispose()
Throw
End Try
End If
Return HttpContext.Current.Session
End Get
End Property
Tags What's this?: Add a tag
Flag as ContentBug
CA2000 and anonymous object initializer      Martin Hudasch   |   Edit   |   Show History

concider we have code like this:

var a = new ImplementsIDisposable { Member = value };

This violates CA2000 because the anonymous instance ' <>g__initLocal0 ' is not disposed before losing its scope.
So as a result you must avoid anonymous object initializers on disposable local variables.

var a = new ImplementsIDisposable();
a.Member = value;
Tags What's this?: Add a tag
Flag as ContentBug
When i do the same trick as described ..      Jarno Burger ... Thomas Lee   |   Edit   |   Show History
CA2000 is still there..
Tags What's this?: Add a tag
Flag as ContentBug
The null check causes CA2000 to be reported      TorbenRahbekKoch   |   Edit   |   Show History
In the C# sample this will still cause CA2000 to be reported:
if (tempPort != null)
{
    tempPort.Close();
}
If the construction of tempPort fails (with an exception) tempPort will be null though, so the check makes sense, but it will still cause the CA2000 check to fail. Sigh. I see no way around this?


Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2012 Microsoft. All rights reserved. Terms of Use | Trademarks | Privacy Statement
Page view tracker