[asp.net]c# OnEventReached 方法内的逻辑

发布时间: 2017/3/26 2:09:50
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

有人可以解释我下面语句而引发事件的重要性。

   EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;

因为我们只指派阈值事件处理程序,为什么我们不能只是简单地呼叫像 ThresholdReached (此,e)

    protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
    {
        EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;
        if (handler != null)
        {
            handler(this, e);
        }
    }
    public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;

解决方法 1:

在这第一条线保护免受争用条件在多线程应用程序中。

想象一下如果一些其他线程取消订阅事件只是之后你检查是否不是 null。

检查 null 是必要的因为没有任何处理程序的事件为 null,你会举出通过调用此类事件。

所以要精确。

此代码不会检查 null,并可能会引发举出︰

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
    ThresholdReached(this, e);
}

这是危险,可能的竞争条件,可能也可能会引发异常︰

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
    if (ThresholdReached != null)
         ThresholdReached(this, e);
}

编辑 (要更好地解释局部变量的行为)︰

有此分配创建本地副本保持其状态的事件。所以如果任何线程取消订阅事件本地副本保持不变在方法调用的其余部分。换句话说委托的行为像复制结构不像复制引用。

下面的代码将打印文本︰

        // let's assume ThresholdReached is null
        ThresholdReached += MyHandler;
        EventHandler<ThresholdReachedEventArgs> localCopy = ThresholdReached ;
        ThresholdReached -= Program_SthEvent;
        if (localCopy != null)
            Console.WriteLine("we have a copy!");

通知如何 localCopy 仍然是状态和价值;

赞助商