From: mick on
Anyone put this straight in my head...

If you dispose an object that without explicitly removing the event
subscription
what happens? Does the event still hang there? Does it prevent the
Dispose()?
If so, what is the point of subbing to an event using an anon. method?

Timer timer = new Timer();
timer.Interval = 2000;
timer.Tick += (s,e) => {
// DO Stuff
timer.Dispose();
};
timer.Start();



mick

From: Adam Clauss on
On 6/24/2010 4:36 PM, mick wrote:
> If you dispose an object that without explicitly removing the event
> subscription
> what happens? Does the event still hang there? Does it prevent the
> Dispose()?
> If so, what is the point of subbing to an event using an anon. method?
>
> Timer timer = new Timer();
> timer.Interval = 2000;
> timer.Tick += (s,e) => {
> // DO Stuff
> timer.Dispose();
> };
> timer.Start();
Two items of interest here:
1) The instance of the timer
2) The instance of your anonymous method

The dispose call is somewhat irrelevant actually. Dispose does not get
rid of the Timer instance, it simply tells the timer to clean up it's
internal resources. That is completely indepenent of the timer / event
/ anonymous method hanging around. The timer instance itself will still
exist and needs to be garbage collected at some point.

More important is when do YOU get rid of any references to "timer" (aka
set to null)?

The timer holds a reference to the anonymous method (via the Timer's
Tick event), so until the timer goes away, the anonymous method cannot
go away. Once all your references to the timer are gone, the timer is
eligible for garbage collection. Once the timer gets garbage
collected*, there will be no more references to the anonymous method and
the anonymous method will then become eligible for garbage collection.

* Qualifying this statement slightly: The GC may "optimize" the process
by recognizing (in the same GC pass) that the "chain" of objects from
Timer -> Tick Event -> anonymous method have no more references and can
be garbage collected all at once (rather than making the Timer go in a
initial pass, and the anonymous method in a later pass). I don't know,
but in either case, it is a tangent and not particularly important to
your question.

-Adam

From: Peter Duniho on
mick wrote:
> Anyone put this straight in my head...
>
> If you dispose an object that without explicitly removing the event
> subscription
> what happens? Does the event still hang there? Does it prevent the
> Dispose()?

As Adam says, Dispose() and event subscriptions really don't have
anything to do with each other.

Subscribing to an event on an object does not affect the
reachability/collectability of the object with the event. Doing so
doesn't in any way change the references to that object.

It can affect whether some _other_ object can be GC'ed; specifically, if
the method subscribed to the event is an instance method of an object,
then the instance of that object used to obtain the method reference
cannot be collected until either the object with the event is no longer
reachable, or the method is unsubscribed from the event.

> If so, what is the point of subbing to an event using an anon. method?

I don't understand the question. Anonymous methods don't really have
anything to do with reachability either.

If your anonymous method does not use anything from the instance of the
object in which it's defined, there is no requirement that it hold a
reference to that object. So in theory, subscribing an anonymous method
to an event might not affect whether any named object in your code is
reachable.

Furthermore, even if the anonymous method holds a reference to the Timer
object, if the only thing referencing the hidden object backing the
anonymous method is that Timer object, and the only thing referencing
the Timer is the hidden object backing the anonymous method, then
neither reference is reachable and both objects can be collected.

The point of using an anonymous method is to do things like taking
advantage of variable capturing, and of course to put a concise event
handler implementation closer to where it's used rather than requiring a
named method for it. It's not a way to control object lifetime.

Pete