3

我已经看到了在 C# 中触发事件的各种编码风格。第一种样式包括以下内容:

- 事件处理程序

    public delegate void NumberReachedEventHandler(object sender, 
    NumberReachedEventArgs e);

-一个事件

    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);
        }
    }

对我来说,似乎一种样式检查“事件”是否为空,而第二种样式检查委托是否为空。但是,我的理解是事件只是委托的一个实例,所以我想知道这两种编写代码的方式是否有任何优势。如果是这样,请解释一下。提前致谢。

4

2 回答 2

11

两者都在检查与事件关联的委托是否为空。

存储到本地的目的是防止多线程代码中出现TOCTOU风格的竞争。

需要注意的是,使用本地人只会消除两个潜在种族之一。有关详细信息,请参阅我 2009 年关于该主题的文章:http: //blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx

还有这个问题:

C# 事件和线程安全

于 2013-08-02T22:41:44.723 回答
0

根据我对这个答案的理解,第一个不是线程安全的,而第二个是。

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);
    }
}
于 2013-08-02T22:42:33.457 回答