Raz*_*t4x 5 c# events delegates event-handling
这段代码为名为的事件添加了新的EventHandler寄存器NewMail(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);
}
Run Code Online (Sandbox Code Playgroud)
(来源:CLR通过C#,第11章事件)我不明白的是do部分,首先我们将newMail分配给prevHandler,然后newMail被更改(在CompareExchange中)到newHandler?然后我们检查newMail!= prevHandler?
我真的很困惑.任何人都可以帮助我理解这里到底发生了什么,特别是在do循环中?
正如评论所说,它是为了提供一种安全的方式来处理多线程环境中的事件。这实际上非常棘手,但它的工作原理如下:
所做的Interlocked.CompareExchange是:if prevHandler == this.NewMail,那么this.NewMail = newHandler
整个操作(比较+影响)是原子的,即一次性完成(不能在操作过程中被另一个线程停止)。
如果NewMail不等于prevHandler,则意味着另一个线程已经运行了相同的代码并且已经修改了事件处理程序。所以我们不会在这里做任何事情,我们将循环并重试,希望下次没有其他线程已经注册了事件处理程序(下次我们将重新读取事件处理程序;其他线程完成的操作)现在将考虑线程)。
另请参阅这个有用的线程。