首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >引发事件的潜在不利因素?

引发事件的潜在不利因素?
EN

Stack Overflow用户
提问于 2013-11-11 17:46:57
回答 3查看 123关注 0票数 11

Microsoft's tutorial on events展示了如何在触发event之前检查null

代码语言:javascript
复制
protected virtual void OnChanged(EventArgs e) 
{
    if (Changed != null)
    {   // Potential Race-condition at this point!
        Changed(this, e);
    }
}

但这将打开一个竞赛条件,如Eric Lippert's blog中所详细描述的,他在其中写道,应该通过本地事件来触发事件,以避免出现竞赛条件:

代码语言:javascript
复制
protected virtual void OnChanged(EventArgs e) 
{
    ChangedEventHandler temp = Changed;  // Local copy of the EventHandler
    if (temp != null)
    {                                    // Race condition avoided by local variable.
        temp(this, e);
    }
}

虽然这是可行的,但它使许多错误的开发人员感到困惑,而不把它放在本地范围内的事件中。

来自DailyCoding的另一种解决方案是始终初始化事件,使其具有一个空处理程序,因此不需要进行空检查:

代码语言:javascript
复制
// Set with empty delegate, will never be null
public event ChangedEventHandler Changed = delegate { };

protected virtual void OnChanged(EventArgs e) 
{
    // Neither Null-check nor local variable is needed; just trigger the event.
    Changed(this, e);
}

这个很有道理,而且很简单。

然而,由于我在网上很少看到这种技术,我认为一定有原因。

用这样的空委托初始化事件有什么坏处吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-11 17:50:40

您将看到一个绝对微小的性能问题,但是在更高级的情况下存在问题,例如序列化和反序列化类可能导致您丢失假事件处理程序,以及缺少空检查然后抛出异常。

票数 1
EN

Stack Overflow用户

发布于 2013-11-11 17:49:21

  • 如果事件是空的,这是一个轻微的性能问题。
  • 如果你在课堂上写了Changed = null,它就会崩溃。
票数 1
EN

Stack Overflow用户

发布于 2013-11-11 21:33:27

在Eric Lippert的博客文章中,他说:

还有其他解决此问题的方法;例如,初始化处理程序,使其具有永不删除的空操作。但是执行空检查是标准模式。

但在此之前,他还说:

删除调用站点周围的代码空检查不会减少代码中的争用条件的数量.更糟的是,这样做缩小了在不消除竞争的情况下可以发生竞赛的窗口,从而使竞赛条件更难检测。

这是因为正如他所描述的,这种情况仍有可能发生。

在将委托值推到堆栈和调用堆栈之间.

因此,基本上,如果您使用一个空的处理程序,您会遇到一些性能损失(这似乎是这里的共识)。所以你得到的是可读性,但最重要的是:奇怪的行为会更明显。(我从性能较低的->更容易调用陈旧处理程序的情况下推断出这一点),因此,如果您完全意识到这样的事情可能发生,并且null检查不困扰您,那么就去做吧。或者不要,如果你不想的话。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19912626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档