private EventHandler _FieldsChanged;
public event EventHandler FieldsChanged
{
    add
    {
        EventHandler handler2;
        EventHandler fieldsChanged = this._FieldsChanged;
        do
        {
            handler2 = fieldsChanged;
            EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value);
            fieldsChanged = Interlocked.CompareExchange<EventHandler>(ref this._FieldsChanged, handler3, handler2);
        }
        while (fieldsChanged != handler2);
    }
    remove
    {
        EventHandler handler2;
        EventHandler fieldsChanged = this._FieldsChanged;
        do
        {
            handler2 = fieldsChanged;
            EventHandler handler3 = (EventHandler)Delegate.Remove(handler2, value);
            fieldsChanged = Interlocked.CompareExchange<EventHandler>(ref this._FieldsChanged, handler3, handler2);
        }
        while (fieldsChanged != handler2);
    }
}
    下面是我最后的理解,也许是错的:
EventHandler handler2;
EventHandler fieldsChanged = this._FieldsChanged;
do
{
    // 两个本地变量都保存着_FieldsChanged的本地引用
    handler2 = fieldsChanged;
    // 事件绑定。这是唯一一句业务代码
    EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value);
    // 如果_FieldsChanged等于handler2,就执行_FieldsChanged=handler3,这里是原子操作,线程安全
    // 如果不等,很明显,有线程冲突存在,数据被别的线程修改过了,这里返回_FieldsChanged到fieldsChanged中去
    fieldsChanged = Interlocked.CompareExchange<EventHandler>(ref this._FieldsChanged, handler3, handler2);
}
while (fieldsChanged != handler2);

// 实际上,整个过程,如果不考虑线程安全,可以直接这么写
_FieldsChanged = (EventHandler)Delegate.Combine(_FieldsChanged, value);
// 这段代码的精妙之处就在于这个线程安全,如果Combine后,别的线程也进来,那就出现了数据丢失
// 当然,常规做法可以是Lock住这段代码,但是,线程冲突的可行性不到1%,为此损失了99%的性能,悲哀呀! 

采集

C#内部关于绑定事件Event的线程安全的更多相关文章

  1. 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  2. 多线程面试题系列(6):经典线程同步 事件Event

    上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...

  3. (92)Wangdao.com_第二十五天_线程机制_H5 Web Workers 分线程任务_事件 Event

    浏览器内核 支撑浏览器运行的最核心的程序 IE 浏览器内核            Trident内核,也是俗称的IE内核Chrome 浏览器内核            统称为 Chromium 内核或 ...

  4. C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较

    使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新 使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和 ...

  5. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

  6. 秒杀多线程第六篇 经典线程同步 事件Event

    原文地址:http://blog.csdn.net/morewindows/article/details/7445233 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权” ...

  7. pythonl练习笔记——threading线程中的事件Event

    1 事件Event 使用方法:e = threading.Event() Event对象主要用于线程间通信,确切地说是用于主线程控制其他线程的执行. Event事件提供了三个方法:wait等待.cle ...

  8. 转--- 秒杀多线程第六篇 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  9. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

随机推荐

  1. 考了3年,工作四年,零基础在职终于拿到CFA证书

    大家都知道CFA Charterholder是独有的全球公认的投资管理从业人员高职业水平和道德水准的有力证明,是金融界卓越专业成就的象征:CFA资格强调和遵循极其严格的职业操守和道德准则,世界各主要发 ...

  2. 【NOIP】OpenJudge - 15:银行利息

    #include<stdio.h>//银行利息 int main() { float a,b; int i,c,d; scanf("%f%f%d",&a,&am ...

  3. 实现mysql在windows server 2008下自动备份

    环境:MySQL   安装位置:D:\MySQL论坛数据库名称为:Db_Test数据库备份目的地:D:\db_bak\ 1.首先新建一个bat文件 rem ********************** ...

  4. ASP.NET没有魔法——ASP.NET与数据库

    在之前的文章中介绍了使用ASP.NET MVC来开发一个博客系统,并且已将初具雏形,可以查看文章列表页面,也可以点击文章列表的其中一篇文章查看详情,这已经完成了最开始需求分析的读者的查看列表和查看文章 ...

  5. 【Java核心】ClassLoader原理及其使用

    又把博客的皮肤换了换,看着更加简洁舒心一些.前段的知识只是略懂,拿过来就能用,只是自己的审美和设计水平有限,实在难以弄出自己特别满意的东西,也算是小小的遗憾吧!言归正传,由于最近涉及到Java核心的东 ...

  6. app启动页问题

    今天自己做的小作品准备提交,就差一个启动页,各种百度,各种搜,结果还好最后终于出来了,和大家分享一下,这个过程中遇到的各种小问题.(注XCode版本为7.2) 1.启动页一般都是图片,因为苹果有4,4 ...

  7. UVa1630,Folding

    区间dp,记忆化搜就可以 st为原串 dp[p][q]存st[p]~st[q]的最优长度,f[p][q]存对应的最优串 从(0,len-1)开始搜,f[0][len-1]为所求ans,回溯条件为p== ...

  8. 前端(各种demo):右侧导航栏的折叠和打开(不使用js)基础版和升级版

    1.给div设置定位. 复习一下—— css中position有五种属性: static:默认值,没有定位 absolute:绝对定位,相对于父级元素进行定位 relative:相对定位 fixed: ...

  9. DES加密And解密

    加密分为:单向加密,双向加密和对称加密. 单向加密:通过对数据进行摘要计算生成密文,密文不可逆推还原.算法代表:Base64,MD5,SHA; 双向加密:与单向加密相反,可以把密文逆推还原成明文,双向 ...

  10. 推荐系统架构-(附ppt&代码)

    Part1.乐视网视频推荐系统 推荐系统:和传统的推荐系统架构无异(基础建模+规则) 数据模块特点:用户反馈服务数据->kv 缓存->log存储 行为日志->解析/聚合->se ...