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?
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?
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.
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.
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
.
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.