Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / September 2003

Tip: Looking for answers? Try searching our database.

CLR designers: Anonymous delegates + events?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Matt Mastracci - 04 Sep 2003 19:51 GMT
I was just reading an earlier thread about how events are strong
references and that subscribing to an event ties your object's lifetime
to that of the event source.

Here's my question: In the next release of the C# language, that is
supposed to support anonymous delegates, how would you be able to bind
an anonymous delegate to an event without causing a memory leak?

Here's an example to illustrate my question: I have a method that, for
the duration of the method's execution, I would like to subscribe to
another object's events.  Using anonymous delegates, this would look
like (I'm guessing at the syntax here):

int nCount = 0;
someobject.SomeEvent +=
   
someobject.Process();

Now, after I've made my Process() method call, I actually have no way to
remove my anonymous delegate (without called GetInvocationList())!
Should the language even allow this to happen?  The delegate would end
up pinning my calling object!

I'm guessing that this might work, but how many developers would expect
the previous code snippet to cause a memory leak?

int nCount = 0;
EventHandler handler =
    new EventHandler( object sender, EventArgs args )
    { nCount++; }
someobject.SomeEvent += handler;
someobject.Process();
someobject.SomeEvent -= handler;

One way might be to have a "weak-reference" delegate that derived from
Delegate, but only held a weak reference to the target of the delegate.
 This could be used any time an anonymous delegate was used.  It would
need to be able to an invoke when its target disappeared (however that
might work).

Any ideas?  I know this stuff isn't available yet, but this situation
will likely come up.

Matt.
Jay B. Harlow [MVP - Outlook] - 04 Sep 2003 20:12 GMT
Matt,
> The delegate would end up pinning my calling object!
Correct: The object would have a reference to the anonymous delegate,
nothing else would have a reference to the anonymous delegate.

Once the object is eligible for GC, the anonymous delegate would be also. If
you maintain a reference to the object, the anonymous delegate will hang
around.

The leak normally comes into play, when you have the reverse condition. You
attach an event handler to an object, then dereference the object, while
maintaining a link to the handler (the anonymous delegate above). Until you
get ride of the handler object, the original object will hang around.

> Now, after I've made my Process() method call, I actually have no way to
> remove my anonymous delegate (without called GetInvocationList())!
> Should the language even allow this to happen?  The delegate would end
> up pinning my calling object!
Yes, this should be allowed! As I suspect in cases similar to this
someobject is going to go away any way so it really doesn't matter if you
can unhook the anonymous delegate.

IMO, if you want the handler to only be active during the call to Process,
then the anonymous delegate is the wrong tool to use.

Hope this helps
Jay

> I was just reading an earlier thread about how events are strong
> references and that subscribing to an event ties your object's lifetime
[quoted text clipped - 40 lines]
>
> Matt.
Matt Mastracci - 04 Sep 2003 20:36 GMT
> Matt,
>
[quoted text clipped - 6 lines]
> you maintain a reference to the object, the anonymous delegate will hang
> around.

And, as long as the anonymous delegate is hanging around, the object
that instantiated the anonymous delegate would be around as well.

It seems as if the potential for a leak could be fairly large in some
cases.  This would be
one example:

 - the object (B) that is attaching to the event holds a reference (the
only reference) to a
significant chunk of memory
 - the object (A) that sources the event lives longer than object (B)

In this case, object B would be kept in memory by a single function's
anonymous delegate.

> The leak normally comes into play, when you have the reverse condition. You
> attach an event handler to an object, then dereference the object, while
> maintaining a link to the handler (the anonymous delegate above). Until you
> get ride of the handler object, the original object will hang around.

This is incorrect.  Subscribing to another object's event does not
constitute a strong reference from the *event sink* to the *event
source*.  The *event source* can disappear at any point.  The *event
sink* cannot disappear without the *event source* first being disposed
of.  Delegates do not keep track of which invocation lists they are part
of.

>>Now, after I've made my Process() method call, I actually have no way to
>>remove my anonymous delegate (without called GetInvocationList())!
[quoted text clipped - 7 lines]
> IMO, if you want the handler to only be active during the call to Process,
> then the anonymous delegate is the wrong tool to use.

There can be cases where you only want to subscribe to events for a
certain amount of time.  The alternatives involve a lot of extra code.

> Hope this helps
> Jay
[quoted text clipped - 43 lines]
>>
>>Matt.
Jay B. Harlow [MVP - Outlook] - 04 Sep 2003 21:22 GMT
Matt,
> And, as long as the anonymous delegate is hanging around, the object
> that instantiated the anonymous delegate would be around as well.
No it wouldn't!

If the only thing referencing the object is the delegate and the only thing
referencing the delegate is the object. You have a circular reference, the
GC will get ride of both of them!

Is the object referencing the delegate the same object that instantiated it?
If not, it sounds like you are assuming that the anonymous object's creator
will have a reference to it, I find this highly unlikely.

> This is incorrect.  Subscribing to another object's event does not
> constitute a strong reference from the *event sink* to the *event
> source*.  The *event source* can disappear at any point.  The *event
> sink* cannot disappear without the *event source* first being disposed
> of.
I'm sorry I believe you are incorrect! There may be a term problem, in what
you & I are interpreting what the other said.

event source = object that has an event that is raised
event sink = object that handles an event

Delegate = a class that contains a reference to a method & an object, when
you invoke the delegate the method is executed on that object.
MulticastDelegate = A linked list of Delegates
Anonymous method = an unnamed method created 'on the fly' that is commonly
the target of a delegate.
Anonymous delegate  = ??? (possibly identified problem) Technically I am
using Anonymous delegate as synonymous with Anonymous method. In my previous
post every place I used Anonymous delegate use Anonymous method instead.

The source maintains a MulticastDelegate to objects with methods that need
to be executed.

The source always has a reference to the sink, as the source calls into the
sink. If you dereference the sink, the source will still have a reference to
it and it lingers. If you dereference the source, it will go away, as the
sinks do not reference it.

> Delegates do not keep track of which invocation lists they are part of.
What do you consider a Delegate? As I consider the delegate itself to be the
invocation list. Do you consider the target method itself to be the delegate
(not the reference to the method, but the method itself).

Although talking about Who references Whom with Delegates makes my head
spin. I am reasonable confident I am correct. (luckily I do not spew green
pea soup).

Hope this helps
Jay

> > Matt,
> >
[quoted text clipped - 96 lines]
> >>
> >>Matt.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.