Weakreference Multicast Delegates

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Having to remember to unregister for events to prevent a ref count seems to
be quite a burden to place on a developer. I have reviewed the
WeakMulticastDelegate solution proposed by Xavier Musy
(http://www.seedindustries.com/blog/x/2004_06_01_archive.html) and Greg
Schechter’s Avalon solution.

1) Is there a more general solution in C#?

2) Why are delegates not weakreferences? It would seem a logical decision to
make - if the only reference to an object is as an event handler it would
seem that it should be GC'd. Weak references would allow for this.

Andrew
 
Hi Andrew,

First of all, I would like to confirm my understanding of your issue. From
your description, I understand that you would like the event handlers to be
GCed automantically. If there is any misunderstanding, please feel free to
let me know.

Based on the code you have provided, I think using WeakReference might
cause the event handler collected by GC at any time, which prevents the
handler from being called. It might make the app unstable.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
An interesting point, Kevin, but I'm trying now to think of a situation
in which I've created an object that listens for events from elsewhere
but has no other references to it, anywhere.

The only thing I can think of that ever came close were a bunch of data
binding classes that I wrote a while back. They subscribe to events on
two sides, and hold references to other objects, but don't _have_ to be
referenced by any other object in order to do their work. Regardless, I
made an ArrayList called "bindings" in the form that created them,
precisely because I didn't trust the delegate lists to keep them out of
the clutches of the GC. So, even if delegates had used weak references
I would still be safe.

Could you give an example of an object that must be kept "alive" even
though there is no reference to it but a delegate? Even DataBindings
have a list in the owning form that holds on to them....
 
Bruce Wood said:
An interesting point, Kevin, but I'm trying now to think of a situation
in which I've created an object that listens for events from elsewhere
but has no other references to it, anywhere.

The only thing I can think of that ever came close were a bunch of data
binding classes that I wrote a while back. They subscribe to events on
two sides, and hold references to other objects, but don't _have_ to be
referenced by any other object in order to do their work. Regardless, I
made an ArrayList called "bindings" in the form that created them,
precisely because I didn't trust the delegate lists to keep them out of
the clutches of the GC. So, even if delegates had used weak references
I would still be safe.

Could you give an example of an object that must be kept "alive" even
though there is no reference to it but a delegate? Even DataBindings
have a list in the owning form that holds on to them....

yes, anonymous methods in C# 2.0 comes to mind.
 
Kevin Yu said:
Hi Andrew,

First of all, I would like to confirm my understanding of your issue. From
your description, I understand that you would like the event handlers to
be
GCed automantically. If there is any misunderstanding, please feel free to
let me know.

Based on the code you have provided, I think using WeakReference might
cause the event handler collected by GC at any time, which prevents the
handler from being called. It might make the app unstable.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Almost. The situation is this. We have a lot of long running singleton
objects - they are called "Manager" objects. One such object is a data
source that fires off events to anyone who is interested when a given set of
data is modified. There are a series of UI based controls that sit around
and render the data when the user has them on the screen. When the controls
are initialized they are hooked up to the "ChangedData" event via the +=
operator. The code is pretty standard:

dataPublisher.ChangedData += new ChangedDataHandler (...);

of course this means I cannot easily -= from the multicast delegate since I
don't keep a reference to the new ChangedDataHandler around. I could have
written:

handler = new ChangedDataHandler(...);
dataPublisher.ChangedData += handler;

and then during the closing of the control:

dataPublisher.ChangedData -= handler;

However this seems to be a lot of code - and in our specific situation we
would need to keep a LOT of delegate variables around only to be used during
unregistration. Instead, I think it is safe to let the MulticastDelegate
check to ensure that the registered objects actually are still valid, and
keep the reference as a WeakReference so that when the consumer of the data
is disposed/closed it is GC'd.

I'm not sure why this would introduce instabilities.

Thanks

Andrew
 
Almost. The situation is this. We have a lot of long running singleton
objects - they are called "Manager" objects. One such object is a data
source that fires off events to anyone who is interested when a given set of
data is modified. There are a series of UI based controls that sit around
and render the data when the user has them on the screen. When the controls
are initialized they are hooked up to the "ChangedData" event via the +=
operator. The code is pretty standard:

dataPublisher.ChangedData += new ChangedDataHandler (...);

of course this means I cannot easily -= from the multicast delegate since I
don't keep a reference to the new ChangedDataHandler around. I could have
written:

handler = new ChangedDataHandler(...);
dataPublisher.ChangedData += handler;

and then during the closing of the control:

dataPublisher.ChangedData -= handler;

This should work, no need to keep a reference. At least in normal
situation. It does not work with remoting though (at least for me I
needed to keep a reference as you show).

dataPublisher.ChangedData += new ChangedDataHandler(this.Handler);
dataPublisher.ChangedData -= new ChangedDataHandler(this.Handler);

Sunny
 
I have a similar situation, although I never considered the garbage
collection problem.

Could you not put the de-registration code in the Dispose methods of
the UI components, and Dispose them when they are no longer useful? I
haven't used Dispose very much, but it strikes me that that is the
"correct" C# idiom for this situation.

Of course, weak-reference delegates just make the whole thing a lot
easier and less error-prone....
 
Back
Top