事件处理程序:此代码中发生了什么
本文关键字:发生了 什么 代码 程序 事件处理 | 更新日期: 2023-09-27 18:22:26
此添加的代码为名为 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 更改为 newHandler(在 CompareExchange 中(?然后我们正在检查 newMail != prevHandler?
我真的有点困惑。谁能帮助我了解这里到底发生了什么,尤其是在 do 循环中?
正如评论所说,它提供了一种安全的方式来处理多线程环境中的事件。这实际上非常棘手,但这是它的工作原理:
-
Interlocked.CompareExchange
是:if prevHandler == this.NewMail
,然后this.NewMail = newHandler
整个操作( 比较+影响(是原子的,即一次完成(不能在操作过程中被另一个线程停止(。
如果
NewMail
不等于prevHandler
,则表示另一个线程已经运行了相同的代码段并且已经修改了事件处理程序。所以我们不会在这里做任何事情,我们将循环并重试,希望下次没有其他线程已经注册了事件处理程序(下次我们将重新读取事件处理程序;现在将考虑另一个线程完成的操作(。
另请参阅此有用的线程。