J
Jeff Clement
I believe the using statement is not behaving as documented
on
http://msdn.microsoft.com/library/en-us/csspec/html/vclrfcsharpspec_8_13.asp
and in the ECMA specs. It sounds like using is simply a
wrapper around some code that calls Dispose on the resource
provided. In the documentation it says that:
using (ResourceType resource = expression) statement
Corresponds to:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
This implies that a using block will simply call Dispose on
the provided resource. It is not responsible for
supressing finalization or anything like that right?
I've written some test code that, I think, proves that the
above documentation is false. The using block is behaving
differently from the simple try finally block. Using does
call Dispose but is somehow preventing the object from
being GC'd.
using System;
namespace ConsoleApplication10
{
class TestClass:IDisposable
{
~TestClass()
{
System.Console.WriteLine("Finalized!");
}
#region IDisposable Members
public void Dispose()
{
System.Console.WriteLine("GC'd");
}
#endregion
}
class Class1
{
[STAThread]
static void Main(string[] args)
{
// Test #1 using a using statement
System.Console.WriteLine("Using Test: Should Call GC
then Finalizer but doesn't");
using (TestClass c1 = new TestClass()) {}
GC.Collect();
// Test #2 using a try/finally equiv to using statement
System.Console.WriteLine("Using Test: Should Call GC
then Finalizer but doesn't");
TestClass c2 = new TestClass();
try {}
finally {if (c2!=null) ((IDisposable)c2).Dispose();}
c2 = null;
GC.Collect();
System.Console.ReadLine();
}
}
}
The output of this program should be:
Using Test: Should Call GC then Finalizer but doesn't
GC'd
Finalized!
Using Test: Should Call GC then Finalizer
GC'd
Finalized!
But what is actually happening is:
Using Test: Should Call GC then Finalizer but doesn't
GC'd
Using Test: Should Call GC then Finalizer
GC'd
Finalized!
Notice the object is never finalized when using using but
it should be because it's dropped out of scope and I have
not suppressed GC for this object.
Can anyone confirm that this is a deviation from the
expected behaviour? I'm using .NET Framework 1.1.
Thanks,
Jeff
on
http://msdn.microsoft.com/library/en-us/csspec/html/vclrfcsharpspec_8_13.asp
and in the ECMA specs. It sounds like using is simply a
wrapper around some code that calls Dispose on the resource
provided. In the documentation it says that:
using (ResourceType resource = expression) statement
Corresponds to:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
This implies that a using block will simply call Dispose on
the provided resource. It is not responsible for
supressing finalization or anything like that right?
I've written some test code that, I think, proves that the
above documentation is false. The using block is behaving
differently from the simple try finally block. Using does
call Dispose but is somehow preventing the object from
being GC'd.
using System;
namespace ConsoleApplication10
{
class TestClass:IDisposable
{
~TestClass()
{
System.Console.WriteLine("Finalized!");
}
#region IDisposable Members
public void Dispose()
{
System.Console.WriteLine("GC'd");
}
#endregion
}
class Class1
{
[STAThread]
static void Main(string[] args)
{
// Test #1 using a using statement
System.Console.WriteLine("Using Test: Should Call GC
then Finalizer but doesn't");
using (TestClass c1 = new TestClass()) {}
GC.Collect();
// Test #2 using a try/finally equiv to using statement
System.Console.WriteLine("Using Test: Should Call GC
then Finalizer but doesn't");
TestClass c2 = new TestClass();
try {}
finally {if (c2!=null) ((IDisposable)c2).Dispose();}
c2 = null;
GC.Collect();
System.Console.ReadLine();
}
}
}
The output of this program should be:
Using Test: Should Call GC then Finalizer but doesn't
GC'd
Finalized!
Using Test: Should Call GC then Finalizer
GC'd
Finalized!
But what is actually happening is:
Using Test: Should Call GC then Finalizer but doesn't
GC'd
Using Test: Should Call GC then Finalizer
GC'd
Finalized!
Notice the object is never finalized when using using but
it should be because it's dropped out of scope and I have
not suppressed GC for this object.
Can anyone confirm that this is a deviation from the
expected behaviour? I'm using .NET Framework 1.1.
Thanks,
Jeff