在以下情况下,我应该锁定事件吗:
事件 foo;
线程 A:将调用 foo += handler;
线程 B:将调用 foo -= handler;
我应该锁定 foo 吗?
(注:已保留原文中的HTML标签)
在 foo
上进行锁定是个不好的主意,因为它的值每次都会改变。你应该在一个不会改变的变量上进行锁定:
private readonly object eventLock = new object();
private EventHandler fooHandler;
public event EventHandler Foo
{
add
{
lock (eventLock)
{
fooHandler += value;
}
}
remove
{
lock (eventLock)
{
fooHandler -= value;
}
}
}
private void OnFoo(EventArgs e)
{
EventHandler handler;
lock (eventLock)
{
handler = fooHandler;
}
if (handler != null)
{
handler(this, e);
}
}
注意,如果您使用类似此类的字段式事件:public event EventHandler Foo;
如果你使用add/remove方法,则会自动在其上加一个"lock(this)"锁,尽管在调用它之前获取处理程序时必须手动添加它(假设您想确保读取最近写入的值)。个人而言,我不喜欢在"this"上加锁,但您可能不介意-这肯定会使代码更简单。
if(foo!= null){foo(...);}
,因为 foo
可能在测试后变为null。此外,它也不能保证您会得到最新的值-这就是为什么我在我的 OnFoo
方法中加了锁。(内存模型可能会出现奇怪的事情...) - Jon Skeet