7
private void NotifyFreeChannelsChanged() //1.
{
    if (FreeChannelsChanged != null)
    {
        FreeChannelsChanged(this, null);
    }
}

private void NotifyFreeChannelsChanged() //2.
{
    NotifyCollectionChangedEventHandler h = FreeChannelsChanged ;
     if (h != null)
         h(this, e);
}

其中哪个更好,为什么。或者这只是额外的检查。不是主要区别。

4

3 回答 3

6

“更好的”?嗯,不包含(特定)竞争条件,一个。MultiCastDelegate 类型是不可变的,并以所有重要的方式使用值类型语义(但是它们引用类型,请参阅this,更重要的是,this),这就是您首先分配它然后检查的原因。问题是:

// this evaluates to true...
if(SomeEvent != null)
{
    // ...but before this line executes, the last 
    // subscriber detached, and now SomeEvent is null. Oops.
    SomeEvent(this, e);
}

您应该问“为什么有人会使用示例 #2?”


顺便说一句,这是使用隐式类型变量 ( var) 的好地方。那些委托类型名称变得很长......

同样有趣的是竞争条件仍然存在,只是更加微妙。如果在分配后删除订阅者会发生什么?好吧,它仍然会被调用,但实际上(我知道)你无能为力。

于 2013-02-22T08:24:32.147 回答
1

第二个很容易适用于我们使用的一组扩展方法,其中 EventHandler 是方法的目标。

public static void Raise(this EventHandler handler, object sender)
{
  if (handler != null)
    handler(sender, EventArgs.Empty);
}

// And then...
TheEvent.Raise(this);

据我所知,将处理程序传递给方法的事实为您提供了本地副本以避免竞争条件。

于 2013-02-22T08:29:15.403 回答
0

第二个是防止可能的线程错误,其中在 null 检查和片段 1 中触发的事件之间发生上下文切换。其他一些线程可以在两者之间将其设置为 null。

因此,除非您的方法易于使用多线程,否则您可以使用更简单的代码片段。

于 2013-02-22T08:24:38.230 回答