c#中的逻辑OnEventReached方法

问题描述:

有人可以在提出事件时解释下面的语句的重要性。c#中的逻辑OnEventReached方法

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; 

有了这个第一线,从多比赛条件保护线程应用程序

想象一下,如果某个其他线程在您检查它是否为空之后取消订阅了事件。

并且检查null是必需的,因为没有任何处理程序的事件为null,您将通过调用此类事件来获取NullReferenceException。

所以要精确。

此代码不检查空和可能引发的NullReferenceException:

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

这是危险的,由于可能的竞争条件,也可能会抛出异常:

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

EDIT(以更好地解释局部变量的行为):

具有此分配可创建维护其状态的本地事件副本。因此,如果在事件本地副本中取消订阅的任何线程在整个剩余的方法调用中保持不变。换句话说,代理的行为就像复制一个不像复制引用的结构一样。

下面的代码将打印文本:

 // 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保持状态和价值;

+0

很好地陈述。做得好。 – Enigmativity

+0

部分回答了我的问题。但是,如果是这样的话,那么下面的说明如何帮助我们解决竞争条件并确保它不会抛出任何异常?毕竟这只是一项任务。 EventHandler handler = ThresholdReached; – DivideByzero

+0

编辑我的答案,以更好地解释什么作业 – pg0xC