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

// 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);
}

(来源:通过C#进行CLR,第11章“事件”)
我不知道是做什么的,首先我们将newMail分配给prevHandler,然后将newMail更改(在CompareExchange中)为newHandler?然后,我们正在检查newMail!= prevHandler吗?
我真的有点困惑。谁能帮助我了解这里到底发生了什么,特别是在do循环中?

最佳答案

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

  • Interlocked.CompareExchange是什么:if prevHandler == this.NewMail,然后是this.NewMail = newHandler
  • 整个操作(比较+影响)是原子,即在一次中完成(无法在操作中间被另一个线程停止)。
  • 如果NewMail不等于prevHandler,则意味着另一个线程已经运行相同的代码,并且已经修改了事件处理程序。因此,我们在这里什么也不做,我们将循环并重试,希望下次那里没有其他线程已经注册了事件处理程序(下一次我们将重新读取该事件处理程序;该操作现在将考虑其他线程完成的操作)。

  • 另请参见此有用的thread

    关于c# - EventHandler : What is going on in this code?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9148585/

    10-10 20:48