事件处理程序和匿名委托/Lambda 表达式
我希望通过使用匿名委托和 lambda 表达式来为 C# 中的事件处理程序创建方法来澄清一些事情,至少对我自己来说是这样。
假设我们有一个添加匿名委托或 lambda 表达式的事件(对于可以使用较新版本的 .NET 的幸运人群来说)。
SomeClass.SomeEvent += delegate(object o, EventArg e) { /* do something */ };
我读到,过去的人们已经忘记了仍然有阻止类被垃圾收集的处理程序的事件。 如何在不将类中的 SomeEvent 设置为 null 的情况下删除添加的处理程序。 以下不是一个全新的处理程序吗?
SomeClass.SomeEvent -= delegate(object o, EventArg e) { /* do something */ };
我可以看到将匿名委托或 lambda 表达式存储在变量中。 但是,至少对我来说,这似乎违背了能够简单、简洁地添加事件处理程序的整个目的。
SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { /* do something */ });
SomeClass.SomeEvent += handler;
// ... stuff
SomeClass.SomeEvent -= handler;
再说一遍,我知道您可以这样做...
public override Dispose(bool disposing)
{
_someEvent = null;
this.Dispose();
}
但我更感兴趣的是从事件中删除动态创建的方法。 希望有人能为我阐明这一点。 谢谢!
I'm hoping to clear some things up with anonymous delegates and lambda expressions being used to create a method for event handlers in C#, for myself at least.
Suppose we have an event that adds either an anonymous delegate or a lambda expression (for you lucky crowds that can use newer versions of .NET).
SomeClass.SomeEvent += delegate(object o, EventArg e) { /* do something */ };
I have read that people in the past have forgotten about events that still have handlers which prevent the class from being garbage collected. How would one go about removing the added handler without just setting SomeEvent to null within the class. Wouldn't the following be an entirely new handler?
SomeClass.SomeEvent -= delegate(object o, EventArg e) { /* do something */ };
I could see storing the anonymous delegate or lambda expression in a variable. But that, to me at least, seems to defeat the entire purpose of being able to simply and succinctly add an event handler.
SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { /* do something */ });
SomeClass.SomeEvent += handler;
// ... stuff
SomeClass.SomeEvent -= handler;
Again, I understand that you could just do...
public override Dispose(bool disposing)
{
_someEvent = null;
this.Dispose();
}
But I'm more interesting with just removing the dynamically created method from the event. Hopefully someone can shed some light onto this for me. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果对象 X 有一个事件处理程序,其目标是对象 Y,则对象 X 处于活动状态意味着对象 Y 无法被垃圾回收。 它不会阻止对象 X 被垃圾收集。
通常情况下,当某些东西被丢弃时,它很快就会变成垃圾,这意味着你没有问题。
事件和 GC 的问题是,如果您忘记从不同对象中删除订阅的处理程序 - 即您有一个已释放的侦听器,但永远不会被垃圾收集,因为仍然存在对它的引用不同对象中的事件。
If object X has an event handler whose target is object Y, then object X being alive means that object Y can't be garbage collected. It doesn't stop object X from being garbage collected.
Normally when something is disposed, it will become garbage pretty soon anyway, which means you don't have a problem.
The problem with events and GC is if you forget to remove a subscribed handler from a different object - i.e. you have a listener which is disposed, but will never be garbage collected because there's still a reference to it from the event in a different object.
我认为问题是你似乎是从这样的假设出发的:将委托分配给对象的事件会阻止它被 GC 。
这作为一个简单的陈述是不正确的。
话虽如此,感知到的问题就消失了。
最初在垃圾收集中一切都是垃圾。 GC 会遍历当前全局和每个堆栈上可用的所有内容以及它们正在引用的其他对象等,将每个对象标记为非垃圾。
这样的绘图过程如何设法到达这个对象?
I think the problem is you seem to be proceeding from the assumption that having a delegate assigned to an object's event prevents it from being GCed.
This as a simple statement is not true.
With that said the perceived problem disappears.
Initially in garbage collection everything is garbage. The GC runs through every thing currently available globally and on each stack and from these those other objects that they are referencing and so on, marking each as not garbage.
How would such a graphing process manage to arrive at this object?
你不能。
就像你不能在其范围之外创建匿名类型一样(除了一些编译器技巧)。
这就是为什么它被称为匿名。
您必须在某处保存引用...或使用反射。
You can't.
Just like you can't create anonymous type outside of its scope (except for some compiler tricks).
That's why it's called anonymous.
You have to save a reference somewhere... or use reflection.