Myself and a colleague are having a difference of opinion on when an object can be garbage collected in .NET. Take the following code:
Stream stream=getStream();
using(var request=new Request(stream))
{
Stream copy=request.Stream;
// From here on can "request" be garbage collected?
DoStuff1();
DoStuff2(copy);
}
My colleague claims that when a release build is run using the server garbage collector that it is valid for the request object to be garbage collected after the call to request.Stream. He asserts that this only happens with the server garbage collector, and never with the workstation garbage collector.
The reason this is that the Request class had a finalizer that was closing the Stream given to the request. As a result, when DoStuff2 went to use the stream it got an "object disposed" exception. Since the finalizer can only be run by the garbage collector my colleague says that a garbage collection must have taken place before the end of the finally block, but after the last use of request
However, it's my belief that since the above code is just shorthand for something like this:
Stream stream=getStream();
Request request=null;
try
{
Stream copy=request.Stream;
// From here on can "request" be garbage collected?
DoStuff1();
DoStuff2(copy);
}
finally
{
if(request!=null)
request.Dispose();
}
Then request cannot be garbage collected after the call to request.Stream at it is still reachable from the finally block.
Also, if it were possible for the garbage collector to collect the object then the finally block would potentially exhibit undefined behavior as Dispose would be called on a GC'd object, which doesn't make sense. Likewise, it isn't possible to optimize away the finally block as an exception could be thrown within the try/using block before any garbage collection had taken place, which would require the finally block to execute.
Ignoring the issue of closing the stream in the finalizer, is it ever possible for the garbage collector to collect the object before the end of the finally block, and in effect optimize away the logic in the finally block?
Disposemethod is doing stuff! - Seanrequestobject before the end of theusing/finallyblock? The ODE is caused by a badly coded finalizer in theRequestobject, but my point is it should never run the finalizer until the end of theusingblock and then only afterDispose. - Sean