【发布时间】:2015-02-03 20:26:14
【问题描述】:
以下模式用于在引发事件时避免竞争条件,以防另一个线程取消订阅 MyEvent,使其为空。
class MyClass
{
public event EventHandler MyEvent;
public void F()
{
EventHandler handler = MyEvent;
if(handler != null)
handler(this, EventArgs.Empty);
}
}
与容易出现这种竞争条件的错误方式相反:
class MyClass
{
public event EventHandler MyEvent;
public void F()
{
if(MyEvent != null)
MyEvent(this, EventArgs.Empty);
}
}
我的问题是,鉴于System.Delegate 是一个引用类型:万一MyEvent 不为空,怎么会
EventHandler handler = MyEvent;
似乎复制它的调用列表,而不是获取引用。
我希望将 MyEvent 委托分配给“处理程序”变量,然后一旦有人更改 MyEvent,“处理程序”引用的对象也会更改。
显然,情况并非如此,否则这个漂亮的小模式将无法正常工作。
我查看了 .NET 源代码,但仍然找不到我的答案(它可能在那里,但我已经找了大约一个小时但找不到它,所以我在这里。) 我还阅读了 C# 语言规范对事件和委托的规定,但它没有解决这个问题。
感谢您的宝贵时间。
【问题讨论】: