using System;
class Program
{
WeakReference wr;
Program()
{
wr = new WeakReference(this, true);
GC.SuppressFinalize(wr);
}
~Program()
{
Console.WriteLine(wr.IsAlive);
}
static void Main()
{
new Program();
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
What should the output of this program be? On .NET 1.1 it's True
(as
expected), but on .NET 2.0 it is False
. On .NET 2.0 the GC has
special support for finalizing WeakReferences, but it fails to take into
account whether GC.SuppressFinalize()
has been called (and this may be by
design, but it's still broken).
This may look academic, but it is actually a real issue in the
implementation of ReferenceQueues on IKVM. Previously I used
GCHandle
to keep a weak
reference back to the reference object that was being monitored, but because
that requires full trust, I changed the code to use
WeakReference
, but that broke it because of the above mentioned
behavior. The work around is easy, but ugly and inefficient, simply keep
these weak references in a global hashtable to make sure they are always
strongly reachable.
.NET really needs a better mechanism for doing post-mortem cleanup (i.e. something like
java.lang.ref.ReferenceQueue
).
P.S. By my new policy, I won't be filing a bug with Microsoft since they
have amply demonstrated not to care about external bug reports.