views:

343

answers:

6

Hi,

I have a method, which has a try/catch/finall block inside. Within the try block, I declare SqlDataReader as follows:

                SqlDataReader aReader = null;          
               aReader = aCommand.ExecuteReader();

In the finally block, the objects which are manually disposed of are those which are set at the class level. So objects in the method which implement IDisposable, such as SqlDataReader above, do they get automatically disposed of? Close() is called on aReader after a while loop executes to get the contents of the reader (which should be Dispose() as that calls Close()). If there is no call to Close(), would this object be closed/disposed of automatically when the method finishes or the object goes out of scope?

EDIT: I am aware of the using() statement but there are scenarios which are confusing me. Thanks

Thanks

+6  A: 

You should use a using {...} block to wrap your IDisposable objects in - the Dispose() method (which for SqlDataReader passes off to the Close() method) will be called when the using block ends. If you do not use using, the object will not be automatically disposed when it goes out of scope - it will be up to the object finalizer, if it has one, to get rid of resources when it is garbage collected

using (SqlDataReader aReader = aCommand.ExecuteReader())
{
    // ... do stuff
}   // aReader.Dispose() called here
thecoop
A: 

Might the Using statement help?

Breandán
+1  A: 

The Dispose pattern doesn't make any guarantees about which objects will call Dispose on which other objects; it may happen sometimes, but you shouldn't care. Instead, it's your responsibility to make sure Dispose() is called for all IDisposable objects. The best way to do that is with the using statement. For example:

using (SqlDataReader aReader = aCommand.ExecuteReader())
{
    // your code
}
RickNZ
+6  A: 

No, objects are not automatically disposed when they go out of scope.

They're not even guaranteed to be disposed if/when they're garbage-collected, although many IDisposable objects implement a "fallback" finaliser to help ensure that they're eventually disposed.

You are resposible for ensuring that any IDisposable objects are disposed, preferably by wrapping them in a using block.

LukeH
A: 

I am puzzled by the statement "In the finally block, the objects which are manually disposed of are those which are set at the class level." By objects set at the class level, do you mean fields? You probably shouldn't be disposing of these within a ordinary method, because then the life-time of the fields is unpredictable, and depends on which methods you happened to have called. It would be better to implement IDisposable and dispose of fields in your Dispose method.

ShellShock
+1  A: 

I agree with all of the above. You should make sure you call Dispose() yourself, and the easiest way to to this is with the using statement (you can also do this yourself in the finally block - this is more verbose, but sometimes necessary). If you don't do this you can find your application leaking unmanaged resources such as handles, or even unmanaged memory, especially if somewhere underneath all of this some COM components are being used, or calls are being made into the Win32 API. This can obviously lead to performance and stability problems, as well as excessive resource usage.

Just because objects that implement IDisposable "should" implement a finaliser that calls their Dispose(bool disposing) method to free unmanaged resources, is no guarantee that this will happen, so you definitely should not rely on it. See, for example, http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx for more information on this point.

Also, something else to bear in mind, is that if your type has members that are disposable, your type should either implement IDisposable (unless the lifecycle of those members is managed by another type, which obviously might get messy), or, if you only use such members in one method, or to implement one particular piece of functionality, you should consider making them local variables/parameters in the methods that use them.

Bart Read