调用事件委托的更好方法是什么

本文关键字:更好 方法 是什么 事件 调用 | 更新日期: 2023-09-27 18:00:26

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

其中哪个更好以及为什么。或者这只是一张额外的支票。不是什么大区别。

调用事件委托的更好方法是什么

"更好"?不包含(特定的(种族条件,一个包含。MultiCastDelegate类型是不可变的,并以所有重要的方式使用值类型语义(它们引用类型,但请参阅此,更重要的是,请参阅此(,这就是为什么您首先分配它,然后进行检查。问题是:

// 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(的好地方。那些委托类型名称变长。。。

同样有趣的是,种族状况仍然存在,只是更微妙而已。如果订阅者在分配后被删除,会发生什么?好吧,它仍然会被调用,但实际上(我知道(你对此无能为力。

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

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

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

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

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