事件处理:发生了什么事在这个代码? [英] EventHandler: What is going on in this code?

查看:145
本文介绍了事件处理:发生了什么事在这个代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个代码,增加了登记新的EventHandler(个),命名为 NEWMAIL 事件(EventArgs类被命名为 NewMailEventArgs

this code that adds registers new EventHandler(s) for an event named as NewMail (the eventargs class is named 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);
}

(来源:通过C#CLR,第11章活动)
我不明白的是,以newHandler的做兼职,首先我们要分配到NEWMAIL prevHandler,然后NEWMAIL被改变(CompareExchange)?然后,如果NEWMAIL!= prevHandler?结果
我真有点糊涂了,我们正在检查。任何一个可以帮助我了解究竟是怎么回事,特别是在做循环?

(source : CLR via C#, chapter 11 Events) What I don't understand is the do part, first we are assigning newMail to prevHandler, then newMail is changed (in CompareExchange) to newHandler? Then we are checking if newMail != prevHandler?
I am really kinda confused. Can any one help me understand what exactly is going on in here, specially in the do loop?

推荐答案

随着评论说,它提供了一种安全的方法来处理在多线程环境中的事件。这是相当棘手实际,但这里的工作原理是:

As the comment says, it's to provide a kind of safety way to deal with events in multi-threaded environment. This is pretty tricky actually, but here's how it works:


  • 这是什么 Interlocked.CompareExchange 是:如果prevHandler == this.NewMail ,那么 this.NewMail = newHandler

整个操作(比较+影响)为原子,即在一个时间完成(不能被停止操作由另一个线程的中间)。

The whole operation (compare + affect) is atomic, i.e. done in one time (cannot be stopped in the middle of the operation by another thread).

如果 NEWMAIL 不等于 prevHandler ,那么就意味着另一个线程已经跑了同一段代码,并且已经修改了事件处理程序即可。所以,我们不会在这里做任何事情,我们将循环再试试,希望下一次没有其他线程已注册的事件处理程序(下一次我们' LL 重新读的事件处理程序;由另一个线程完成的动作进行现在考虑)

If NewMail is not equal to prevHandler, then it means another thread already ran the same piece of code and already modified the event handler. So we won't do anything here and we'll loop and try again, hoping next time there is no other thread that already registered an event handler (next time we'll re-read the event handler; the operation done by the other thread will be now taken into account).

又见这个有用线程

这篇关于事件处理:发生了什么事在这个代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆