调用事件委托的更好方法是什么
本文关键字:更好 方法 是什么 事件 调用 | 更新日期: 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。
因此,除非您的方法倾向于多线程,否则您可以使用更简单的代码段方法。