Ham*_*ein 12 .net c# events memory-management
我最近一直在研究内存管理,并一直在研究如何管理事件,现在,我看到了事件订阅的显式添加/删除语法.
我认为这很简单,添加/删除只允许我在订阅和取消订阅时执行其他逻辑?我得到它了,还是有更多的东西?
此外,虽然我在这里,任何清理我的事件处理的建议/最佳实践.
Yoc*_*mer 14
添加/删除属性与使用其他成员的set/get属性的逻辑基本相同.它允许您在注册事件时创建一些额外的逻辑,并封装事件本身.
你想要做的一个很好的例子就是在不需要时停止额外的计算(没有人在听这个事件).
例如,假设事件是由计时器触发的,如果没有人注册事件,我们不希望计时器工作:
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
private EventHandler _explicitEvent;
public event EventHandler ExplicitEvent
{
add
{
if (_explicitEvent == null) timer.Start();
_explicitEvent += value;
}
remove
{
_explicitEvent -= value;
if (_explicitEvent == null) timer.Stop();
}
}
Run Code Online (Sandbox Code Playgroud)
您可能想要用对象锁定添加/删除(事后想法)......
是的,添加/删除语法允许您实现自己的订阅逻辑.当您将它们遗漏(事件的标准符号)时,编译器会生成标准实现.这就像自动属性.
在下面的示例中,Event1和Event2之间没有真正的区别.
public class Foo
{
private EventHandler handler;
public event EventHandler Event1
{
add { handler += value; }
remove { handler -= value; }
}
public event EventHandler Event2;
}
Run Code Online (Sandbox Code Playgroud)
但这与"清理"处理程序有关.订阅类应该取消订阅.出版课对这方面无济于事.
想象一个可以"清理"其事件订阅列表的类.只有在Disposed本身时它才能明智地做到这一点,然后它不太可能有效率,因为Disposed类通常在Disposed之后不久就可收集.
添加/删除语法通常用于将事件实现“转发”到另一个类。
清理订阅(而不是“事件句柄”)最好通过实现IDisposable.
更新:哪个对象应该实现有一些变化IDisposable。Rx 团队从设计角度做出了最佳决定:订阅本身就是IDisposable。常规 .NET 事件没有表示订阅的对象,因此需要在发布者(定义事件的类)和订阅者(通常是包含要订阅的成员函数的类)之间进行选择。虽然我的设计本能更喜欢创建订阅者IDisposable,但大多数现实世界的代码都会创建发布者IDisposable:这是一个更容易的实现,并且可能存在没有实际订阅者实例的情况。
(也就是说,如果代码实际上完全清除了事件订阅。大多数代码不会。)