【问题标题】:EventHandler: What is going on in this code?EventHandler:这段代码发生了什么?
【发布时间】:2012-02-05 10:43:13
【问题描述】:

此代码为名为 NewMail 的事件添加注册新的 EventHandler(s)(eventargs 类名为 NewMailEventArgs

// A PUBLIC add_xxx method (xxx is the event name)
// Allows methods to register interest in the event.
public void add_NewMail(EventHandler<NewMailEventArgs> value) {
  // The loop and the call to CompareExchange is all just a fancy way
  // of adding a delegate to the event in a thread-safe way.
  EventHandler<NewMailEventArgs> prevHandler;
  EventHandler<NewMailEventArgs> newMail = this.NewMail;
  do {
     prevHandler = newMail;
     EventHandler<NewMailEventArgs> newHandler = (EventHandler<NewMailEventArgs>)Delegate.Combine(prevHandler, value);
     newMail = Interlocked.CompareExchange<EventHandler<NewMailEventArgs>>(ref this.NewMail, newHandler, prevHandler);
    }
  while(newMail != prevHandler);
}

(来源:CLR via C#,第 11 章事件) 我不明白的是do部分,首先我们将newMail分配给prevHandler,然后将newMail(在CompareExchange中)更改为newHandler?然后我们检查是否 newMail != prevHandler?
我真的有点困惑。谁能帮我理解这里到底发生了什么,特别是在 do 循环中?

【问题讨论】:

    标签: c# events delegates event-handling


    【解决方案1】:

    正如评论所说,它是提供一种在多线程环境中处理事件的安全方式。这实际上非常棘手,但它是这样工作的:

    • Interlocked.CompareExchange 是:if prevHandler == this.NewMail,然后是this.NewMail = newHandler

    • 整个操作(比较+影响)是原子的,即一次性完成(不能在操作中间被另一个线程停止) .

    • 如果NewMail 不等于prevHandler,则意味着另一个线程已经运行了相同的代码并且已经修改了事件处理程序。所以我们不会在这里做任何事情,我们会循环再试一次,希望下次没有没有其他线程已经注册了事件处理程序(下次我们' ll 重新读取事件处理程序;现在将考虑其他线程完成的操作)。

    另请参阅这个有用的thread

    【讨论】:

      猜你喜欢
      • 2016-06-09
      • 2018-07-28
      • 2012-08-29
      • 2014-11-12
      • 2012-07-26
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多