A static analysis tool keeps telling me that my C# code has resource leaks in it.
Here's an example:
StringReader reader = new StringReader(...);
// do something with reader
...
} // static analysis tool cries that I've leaked **reader**
Is my tool correct? If so, why?
Edit (replying to comment) - My static analysis tool says that I've got a bunch of resource leaks. I know from this forum that certain Java AWT objects need to be explicitly freed, otherwise a leak occurs. Are there C# objects that need to be explicitly freed?
Yeah, your code is leaking badly. It should be like this:
using (StringReader reader = new StringReader(...))
{
}
Every class that implements IDisposable
needs to be wrapped in a using block to ensure that the Dispose
method is always called.
UPDATE:
Elaborating: in .NET there's the IDisposable interface which defines the Dispose method. Classes that implement this interface (like files streams, database connections, readers, ...) might contain pointers to unmanaged resources and the only way to ensure that those unmanaged resources/handles are freed is to call the Dispose method. So in .NET to ensure that some code is called even if an exception is thrown is to use a try/finally statement:
var myRes = new MyResource(); // where MyResource implements IDisposable
try
{
myRes.DoSomething(); // this might throw an exception
}
finally
{
if (myRes != null)
{
((IDisposable)myRes).Dispose();
}
}
People writing C# code have quickly realized that writing this every time you was dealing with a disposable resource was a PITA. So they've introduced the using
statement:
using (var myRes = new MyResource())
{
myRes.DoSomething(); // this might throw an exception
}
which is kinda shorter.
Your code isn't actually leaking anything in this specific case, because StringReader
doesn't really have any resources to clean up, just like MemoryStream
doesn't. (With MemoryStream
you can still end up needing to dispose of it if you're using it asynchronously or remoting it... but in straightforward cases it doesn't matter.)
However, it's a good idea to dispose of anything which implements IDisposable
just on principle. This will avoid you leaking (perhaps temporarily) unmanaged resources such as file handles.
For example, suppose you changed your code to:
StreamReader reader = new StreamReader("file.txt");
...
If you don't close or dispose reader
here (in a finally
block or via a using
statement) it will hold the file open until whatever type is directly holding the OS file handle is finalized. Disposing of things explicitly not only frees unmanaged resources earlier - it also takes finalizable objects off the finalization queue, which means they can be garbage collected earlier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With