此代码为名为的事件添加注册新的 EventHandler(s)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);
}
(来源:CLR via C#,第 11 章事件)
我不明白的是 do 部分,首先我们将 newMail 分配给 prevHandler,然后 newMail 更改(在 CompareExchange 中)为 newHandler?然后我们检查 newMail != prevHandler 是否?
我真的有点困惑。任何人都可以帮助我理解这里到底发生了什么,特别是在 do 循环中?
正如评论所说,它是为了提供一种安全的方式来处理多线程环境中的事件。这实际上非常棘手,但它的工作原理如下:
什么是Interlocked.CompareExchange
is : if prevHandler == this.NewMail
, then this.NewMail = newHandler
整个操作(比较+影响)是atomic, i.e. 一次性完成(不能在操作过程中被另一个线程停止)。
If NewMail
不等于prevHandler
,那么这意味着另一个线程已经运行了相同的代码并且已经修改了事件处理程序。所以我们不会在这里做任何事情,我们会循环并重试,希望下次有没有其他线程已经注册了一个事件处理程序(下次我们将re-read事件处理程序;现在将考虑另一个线程完成的操作)。
另请参阅这个有用的thread https://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)