我已经看到了各种编码样式来在C#中触发事件。 第一种风格包括以下内容:
-an event handler
public delegate void NumberReachedEventHandler(object sender,
NumberReachedEventArgs e);
-an event
public event NumberReachedEventHandler NumberReached;
- 以及触发事件的方法
protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
if(NumberReached != null)
{
NumberReached(this, e);
}
}
然而,第二种风格有一种不同的方法来激活事件:
protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
NumberReachedEventHandler handler = NumberReached;
if(handler != null)
{
handler(this, e);
}
}
对我来说,似乎有一种样式检查“event”是否为null,第二种样式检查委托是否为null。但是,我的理解是一个事件只是一个委托的实例,所以我想知道编写代码的方式是否有任何优势。如果是,请解释。提前致谢。
答案 0 :(得分:11)
两者都在检查与事件关联的委托是否为空。
存储到本地的目的是防止多线程代码中的TOCTOU式竞争。
重要的是要注意,使用本地只能消除两个潜在比赛中的一个。有关详细信息,请参阅我在2009年关于该主题的文章:http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx
还有这个问题:
答案 1 :(得分:0)
根据我对this的理解,第一个不是线程安全的,而第二个是。
protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
//If number reached is changed from after this check
if(NumberReached != null)
{
//and between this call, it could still result in a
//NullReferenceException
NumberReached(this, e);
}
}