c# - 如何处理包含事件的局部变量

标签 c#

<分区>

Possible Duplicate:
Do event handlers stop garbage collection from occuring?

我有一个这样的 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());
}

我点击按钮两次后,控制台会输出两次时间戳。 但是观察者是一个局部变量! 它出什么问题了? 我怎样才能弄清楚它呢?

最佳答案

watcher 是一个局部变量,但不一定会影响对象。您已要求 GeoCoordinateWatcher 启动 - 我希望它能有效地维护对自身的引用,或将其存储在适当的地方。

听起来或者您应该在单击按钮后禁用它,或者您需要将观察者保留在一个实例变量中,以便您可以处理旧的一个并创建一个新的。 (虽然我不确定为什么这会有用。)

编辑:由于这里有两个不正确的答案,让我澄清一下……事件发布者(在本例中为观察者)引用了处理程序委托(delegate)。如果这些委托(delegate)引用实例方法(就像在本例中那样),那么就会引用包含该方法的类型的实例:

 Event publisher => delegate => instance of type with handler method

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

换句话说,如果 GeoCoordinateWatcher 没有做一些“特殊”的事情(可能在 Start 方法中),它可能被垃圾收集.没有从事件处理程序事件发布者的隐式引用,这阻止了事件发布者以这种方式被垃圾收集。

关于c# - 如何处理包含事件的局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10992100/

相关文章:

c# - 如何禁用特定 ASP.NET Core 5.0 Web API 操作的自动模型绑定(bind)?

c# - "this"有什么用?

c# - 将字符串转换为 HttpPostedFileBase

c# - 集成 Facebook 聊天

c# - 将颜色定义为静态资源

C# UWP 使用 System.IO.Directory 返回空数组?

c# - 无法解析类型的符号

asp.net 中的 C# 列表转换

c# - 按特定顺序对 IQueryable 进行排序

c# - 用事件实现观察者模式