0

This Question based on this question: How to dispose the local variable that contains event

Someone said:one event handler to an instance,the reference count of the instance will added? why?

Community
  • 1
  • 1
Dozer
  • 5,025
  • 11
  • 36
  • 52
  • see this thread, it may be a help http://stackoverflow.com/questions/506092/is-it-necessary-to-explicitly-remove-event-handlers-in-c-sharp – Habib Jun 12 '12 at 12:57
  • 2
    That answer is wrong, basically - the answerer has his concepts the wrong way round. I've added a comment to the answer. – Jon Skeet Jun 12 '12 at 13:00

3 Answers3

2

Your linked question, as Jon Skeet states, has it backwards. The only thing keeping watcher alive is perhaps its own internal implementation where it may (or may not) register an event with a lower-level object that is responsible for feeding back "ticks". -but this is just conjecture.

Clicking the button twice will yield two separate watcher instances, each with one subscriber to the PositionChanged event (which just happens to be the same method on the same instance).

Importantly, it isn't the PositionChanged subscriber that is keeping watcher alive after the method quits - it is something else (I suspect buried within the GeoCoordinateWatcher implementation). When the method exits, a reference to a particular instance of watcher is correctly popped off the stack, but due to another reference being held on watcher the effective reference count in the eyes of the CLR is still greater than zero - therefore, not eligible for garbage collection.

Because of this, it will continue on to fire the PositionChanged event. As nothing in the event stops the watcher from continuing, I'm going to guess you may have a memory leak because each button click will create and leave alive a watcher instance.

You either need to store and use only one GeoCoordinateWatcher class, or close-off / dispose / stop it each time you handle the event.


The usual consideration with events and subscriptions is being mindful of short-lived objects subscribing to long-lived objects.

Delegates hold references to a particular method in a particular instance of a class (or just the type itself if it were a static method). Subscribing to an event causes the event publisher to inadvertently hold a reference to the subscriber instance via the subscription's delegate.

Obviously, if you register a static method as an event handler, you won't get this reference count because there is no instance.

A memory leak can occur if the subscriber is short-lived and the event publisher is long-lived, if you don't unsubscribe. Assume the subscriber would like to be eligible for GC, because it has an active subscription against an event somewhere and that object still lives, it cannot be eligible until it is removed from that subscription list.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
0

Cause by calling GeoCoordinateWatcher.Start you start a new task. Even if it declared in your code like a local variable, it will continue live after the exit of the scope of the function.

You can think about this, like if you start a 3rd part process from the function. Function's scope gone, but the process still live.

In the link provided, if you click button twice, this will lead 2 different instances of the GeoCoordinateWatcher be handled by the same event handler. So that event handler will be invoked twice from 2 diffrent instances of GeoCoordinateWatcher.

Tigran
  • 61,654
  • 8
  • 86
  • 123
0

When you create a delegate object, it contains the Method and Target properties. The Target property points to the object whose context the Target method will be called in (first parameter, aka this).

Under certain circumstances, the reference to the delegate object will be active, hence preventing the Target instance from being GCed. It usually happens when you have a plugin/addin-based application, or some other sort of late-bound situation, or you're doing a lot of work with delegates and delegate objects are stored in some collection, or you have a static field with a delegate object, (since static fields are never collected) etc.

Keep in mind that garbage collection is not susceptible to the "circular reference" problem; for an object to be deemed "useful", it has to be reachable from the current stack.

Mr. TA
  • 5,230
  • 1
  • 28
  • 35