B
Bruce Wood
In messing about with weak reference delegates, I think I've figured
something out. It seems painfully obvious now, but I just want to be
100% sure.
When I say:
collection.ItemAdded += new
ItemAddedEventHandler(this.Collection_ItemAdded);
....that "new" is creating a small object on the heap. The object
contains the necessary information for calling Collection_ItemAdded
when the event is fired. Is this so?
I believe it is, because I was placing an intermediary object between
the ItemAdded event (list of subscribers) and the delegate: an object
that held a WeakReference to the "new ItemAddedEventHandler". Every
time the event was raised, no matter how soon, I found that the
WeakReference pointed to null: the Target had already been
garbage-collected.
My conclusion is that the "new ItemAddedEventHandler" creates a
full-status object on the heap, so if I point to it via a WeakReference
(and, of course, that's the only thing pointing to it), the GC just
swoops down and collects it on the next go-around.
I'm busy revamping my WeakReference delegate structure to hold a
WeakReference to the subscribing object itself, plus MethodInfo for
calling the delegate method. That, I am sure, will have the intended
effect: provide event subscription while still allowing the subscribing
object to be garbage-collected.
Am I on the right track here? Or do I have a mistaken impression of
what's going on. For those who prefer to read code, here is my
WeakReference delegate intermediary class:
public class ItemAddingWeakReference : WeakReference
{
private EventInfo _provider;
public ItemAddingWeakReference(ItemAddingEventHandler subscriber,
EventInfo provider) : base(subscriber)
{
this._provider = provider;
}
public ItemAddingWeakReference(ItemAddingEventHandler subscriber) :
this(subscriber, null)
{ }
public void Handler(object sender, IKeyedInsertDeleteEventArgs ide)
{
ItemAddingEventHandler h = (ItemAddingEventHandler)this.Target;
if (h != null)
{
h(sender, ide);
}
else if (this._provider != null)
{
this._provider.RemoveEventHandler(null, new
ItemAddingEventHandler(this.Handler));
}
}
}
....whenever Handler is invoked, this.Target is always null (already
GC'd).
something out. It seems painfully obvious now, but I just want to be
100% sure.
When I say:
collection.ItemAdded += new
ItemAddedEventHandler(this.Collection_ItemAdded);
....that "new" is creating a small object on the heap. The object
contains the necessary information for calling Collection_ItemAdded
when the event is fired. Is this so?
I believe it is, because I was placing an intermediary object between
the ItemAdded event (list of subscribers) and the delegate: an object
that held a WeakReference to the "new ItemAddedEventHandler". Every
time the event was raised, no matter how soon, I found that the
WeakReference pointed to null: the Target had already been
garbage-collected.
My conclusion is that the "new ItemAddedEventHandler" creates a
full-status object on the heap, so if I point to it via a WeakReference
(and, of course, that's the only thing pointing to it), the GC just
swoops down and collects it on the next go-around.
I'm busy revamping my WeakReference delegate structure to hold a
WeakReference to the subscribing object itself, plus MethodInfo for
calling the delegate method. That, I am sure, will have the intended
effect: provide event subscription while still allowing the subscribing
object to be garbage-collected.
Am I on the right track here? Or do I have a mistaken impression of
what's going on. For those who prefer to read code, here is my
WeakReference delegate intermediary class:
public class ItemAddingWeakReference : WeakReference
{
private EventInfo _provider;
public ItemAddingWeakReference(ItemAddingEventHandler subscriber,
EventInfo provider) : base(subscriber)
{
this._provider = provider;
}
public ItemAddingWeakReference(ItemAddingEventHandler subscriber) :
this(subscriber, null)
{ }
public void Handler(object sender, IKeyedInsertDeleteEventArgs ide)
{
ItemAddingEventHandler h = (ItemAddingEventHandler)this.Target;
if (h != null)
{
h(sender, ide);
}
else if (this._provider != null)
{
this._provider.RemoveEventHandler(null, new
ItemAddingEventHandler(this.Handler));
}
}
}
....whenever Handler is invoked, this.Target is always null (already
GC'd).