【问题标题】:C# EventHandler documentation code exampleC# EventHandler 文档代码示例
【发布时间】:2021-01-01 17:07:52
【问题描述】:

我正在阅读有关 EventHandlers 的 .NET 文档,但不理解来自 https://docs.microsoft.com/en-us/dotnet/standard/events/ 的这段代码:

class Counter
{
    public event EventHandler ThresholdReached;

    protected virtual void OnThresholdReached(EventArgs e)
    {
        EventHandler handler = ThresholdReached;
        handler?.Invoke(this, e);
    }

    // provide remaining implementation for the class
}

局部变量handler的作用是什么?为什么不直接调用 TresholdReached TresholdReached?.Invoke(this, e); 呢? 类似的例子在这里: https://docs.microsoft.com/en-us/dotnet/api/system.eventhandler-1?view=net-5.0

【问题讨论】:

  • 局部变量handler的作用是什么,在这种情况下,只是一个简短的例子来说明@987654328 @ 对象是强类型的。我认为编译器无论如何都会摆脱局部变量。

标签: c# .net


【解决方案1】:

局部变量handler的作用是什么?

可能没有。在代码正确性方面当然没有理由。它似乎是旧的、预空条件运算符版本的文档的保留,其中需要将事件字段 ThresholdReached 复制到局部变量中以安全地解决竞争条件在引发事件和可能取消订阅它的任何其他代码之间。正如您所指出的,使用空条件运算符,代码可以很简单,通过事件字段本身调用。

我只说“可能”是因为我猜文档的作者希望通过更明确的代码形式实现其他教学目标的可能性很小。但我无法想象那可能是什么,而且它显然会干扰对代码的一般理解(即分散对重要部分的注意力)。

我在页面上提交了一条评论,让 Microsoft 知道该问题。我认为 Microsoft Git 存储库中可能还有一个地方,您可以在其中提交文档问题,如果您愿意的话。

我的经验是,无论以何种方式将问题传达给 Microsoft,他们通常都会在相对较短的时间内解决问题。我猜想在接下来的几周内,该段落将得到修复,而这个问题将不再相关。 :)

【讨论】:

【解决方案2】:

最后,我在发布此问题后几乎立即找到了答案(这困扰了我好几天)。 用 cmets 阅读 @lc. 对这个问题的回答: Events - naming convention and style 引导我到这个页面: https://docs.microsoft.com/en-us/archive/blogs/ericlippert/events-and-races

所以答案是:本地处理程序变量有效地复制不可变委托并使其成为线程安全的。 他们本可以在该文档页面上提及它。

编辑: 请参阅@Peter Duniho 答案和 cmets。

【讨论】:

  • “所以答案是:本地处理程序变量有效地复制不可变委托并使其成为线程安全的”——这不是一个真正的答案,因为代码已经是线程的没有局部变量副本是安全的。确实,这似乎首先是您问题的症结所在。我看不出过时的文档或博客文章如何解决与过时技术是否仍然相关的问题。
  • 复制事件处理程序实例一开始就不是线程安全的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 2021-07-19
  • 1970-01-01
相关资源
最近更新 更多