如何处置包含事件的局部变量

Doz*_*zer 1 c#

可能重复:
事件处理程序是否阻止垃圾收集发生?

我有一个像这样的wp7应用程序:

private void button1_Click(object sender, RoutedEventArgs e)
{
    GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
    watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
    watcher.Start();
}

void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
    Debug.WriteLine(e.Position.Timestamp.ToString());
}
Run Code Online (Sandbox Code Playgroud)

单击两次按钮后,控制台将输出两次Timestamp.但观察者是一个局部变量!它出什么问题了?我怎么能打扰它呢?

Jon*_*eet 8

watcher是一个局部变量,但这不会影响对象.你已经要求GeoCoordinateWatcher开始了 - 我希望它能够有效地保持对自身的引用,或者在适当的地方存储它.

这听起来像要么你应该一旦它被点击禁用按钮,或者你需要保持观察者的一个实例变量,这样就可以处理旧之一,并创建一个新的.(我不知道为什么那会有用.)

编辑:由于这里有两个不正确的答案,让我清楚一点......事件发布者(在这种情况下是观察者)引用了处理程序代理.如果这些委托引用实例方法(就像在这种情况下那样),那么就会引用包含该方法的类型的实例:

 Event publisher => delegate => instance of type with handler method
Run Code Online (Sandbox Code Playgroud)

这意味着只要发布者不是垃圾收集(并且事件处理程序仍然存在),就无法收集与该委托关联的实例.它不会阻止发布者自己被垃圾回收.

换句话说,如果GeoCoordinateWatcher没有做"特殊"的事情(可能在Start方法中),它可能是垃圾收集.从事件处理程序事件发布者没有隐式引用,这会阻止它以那种方式进行垃圾回收.