Do I need to dispose of a resource which is not actually used?
i have a stupid question, but i want to hear the community here.
So here is my code:
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
return true;
}
My question, is it any different开发者_运维技巧 than:
(FtpWebResponse)request.GetResponse();
return true;
Which one is better in general? which one in terms of GC and why?
The first is better, but not in terms of GC. WebResponse
implements IDisposable
because it has resources that need to be released such as network connections, memory streams, etc. IDisposable
is in place because you, as the consumer, know when you are done with the object and you call Dispose
to notify the class you're done with it, and it is free to clean up after itself.
The using
pattern really just calls Dispose
under the hood. E.g. your first example is actually compiled to be this:
FtpWebResponse response = (FtpWebResponse)request.GetResponse()
try
{
}
finally
{
((IDisposable)response).Dispose();
}
return true;
This is separate from the garbage collector. A class could also clean up resources in the finalizer, which gets called from GC, but you should not rely on that to happen for two reasons:
- It could be a very long time before GC finally comes around, which means those resources are sitting there being consumed for no good reason.
- It might not actually clean up resources in the finalizer anyway
The first one is better.
The difference is that the using
statement will call dispose on the object wrapped in it. It will correctly dispose of held resources.
From MSDN, the using statement:
Provides a convenient syntax that ensures the correct use of IDisposable objects.
I appreciate that you are not interested in the response. However, the response object has been created, initialised and returned to your code whether you wanted it or not. If you don't dispose it, then it will hang around consuming resources until the GC eventually gets round to finalizing it.
I agree with what others said, but if you have such hate for the using() syntax, you could do:
((IDisposable)request.GetResponse()).Dispose();
return true;
The GC doesn't care about anything other than memory, so if you've got plenty of memory and are not consuming much of it, it might be a very long time until it does a GC. During that entire time the unmanaged resources, such as network connections, file handles, database connections, graphics handles etc., remain tied up by the objects that are waiting to be GC'd. This can cause you to run out of these resources and the GC will be oblivious because it doesn't monitor unmanaged resources.
So if you put your code in a loop and kept calling it, without calling Dispose, you might find it quickly degrades in performance(processes fighting for scarce resources) or gives you an exception due to a lack of the unmanaged resources. It depends on the context of how it is being called and how you are creating other related objects. Rather than analyze each situation, it is always safest to call Dispose as soon as you are done with the instance.
It is true that eventually Dispose will be called by the GC on an object that has gone out of scope/is no longer referenced, but this is indeterministic. Being indeterministic, you could see different results in how soon resources are free'd when testing vs production and lead to random Exceptions for failure to allocate resources when they run out. If you could choose between consistent deterministic behavior of your application and inderterministic, you'd probably want deterministic, unless maybe you are trying to confuse your Testers.
精彩评论