views:

144

answers:

5

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?

+7  A: 

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.

Oded
Why the downvote?
Oded
No idea, so I upvoted to compensate.
Steven Sudit
It was probably from someone who still thinks calling `Dispose` is optional. Here is a +1 to offset...even though Steven already did.
Brian Gideon
@Steven Sudit, @Brian Gideon - thanks. I still want to know why I got downvoted...
Oded
@Oded: I've learned that sometimes you just get downvoted for no apparent reason. I try not to stress over it.
Steven Sudit
@Steven Sudit - well aware of that... still get frustrated when it is really not apparent.
Oded
@Oded: I assure you that I am entirely sympathetic and can only hope that some of the people brave enough to anonymously downvote you have the integrity to follow up with an explanation. Frankly, I couldn't care less about the points, and I can't imagine that they have much impact on your huge score, either, but I am personally bothered by the lack of opportunity to hear the actual objections so that I can learn from them.
Steven Sudit
@Steven Sudit - indeed. How can one improve without proper feedback, eh?
Oded
+11  A: 

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:

  1. 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.
  2. It might not actually clean up resources in the finalizer anyway
Rex M
as you can see in my comments, the response is not playing any role here. i'm completely ignore it.
Or A
@Or A: Whether you care about the response or not, you're still calling `GetResponse` which means that the returned object still needs to be disposed. (And the recommended pattern to do that would usually be a `using` block.)
LukeH
+4  A: 

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.

Christian Hayter
+2  A: 

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; 
Moose
Yeah, this is fine, although `using` is better in almost all other cases.
Steven Sudit
And the reason `using` is better, is that it ensures that Dispose is called even if an exception occurs.
AaronLS
Using is better if an exception could occur between the time the object is created and the time it is disposed. The only way that could occur in the code above would be if GetResponse somehow returned something other than an iDisposable, in which case Using wouldn't help anything anyhow.
supercat
I agree with both of you. I was just offering an alternative because it seems the OP just doesn't want to HAVE to assign the Response to a variable to use the using().
Moose
+1  A: 

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.

AaronLS