Shawn A. Van Ness wrote:
> How could the finalizer decide to collect an object, if one or more
> threads is currently executing code against it? (Put simply: doesn't
> the 'this' pointer count as a reachable reference, for the duration of
> any instance-method call?)
The easiest way to think about this (no pun intended ;-)) is to imagine
that the method in question is being inlined, now it becomes much easier
to see that the this pointer can go away (and thus the object becomes
unreachable) while the native code is running. So yes, the GC is allowed
to collect objects that still have methods running.
> (b) If GC.KeepAlive(this) really is necessary, ever, then it would
> seem prudent and necessary to call it at the bottom of *every*
> instance method, regardless of whether it has any IntPtr fields or
> not...?
Badly written code could indeed suffer the same fate. Try this:
using System;
class Whatever {
bool disposed;
public void DoIt() {
if(disposed)
throw new ObjectDisposedException("Whatever");
}
public void Dispose() {
disposed = true;
}
}
public class Test {
Whatever obj = new Whatever();
static void Main() {
Test t = new Test();
t.DoIt();
}
void DoIt() {
Whatever tmp = obj;
GC.Collect();
tmp.DoIt();
}
~Test() {
Console.WriteLine("~Test"); obj.Dispose();
}
}
This is why you should never dispose of managed resources in your
finalizer (and in general you shouldn't have a finalizer, except when
you own an unmanaged resource).
Regards,
Jeroen
===================================
This list is hosted by DevelopMentor� http://www.develop.com
View archives and manage your subscription(s) at http://discuss.develop.com