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. Linux下Apache https认证

    参考:http://kyfxbl.iteye.com/blog/1910891 http://showerlee.blog.51cto.com/2047005/1266712 一.环境 httpd:A ...

  2. apache、php隐藏http头部版本信息的实现方法

    1.apache隐藏头部版本信息,编辑httpd.conf文件,找到: ServerTokens OS ServerSignature On 修改为: ServerTokens ProductOnly ...

  3. Elixir游戏服设计一

    在Erlang游戏服设计总结http://www.cnblogs.com/rubyist/p/5530575.html里, 我提到我想要的游戏服设计方法,希望以应用做为基础构建块.最近我在学习elix ...

  4. Golang:使用自定义模板发送邮件

    https://medium.com/@itsHabib/sending-emails-with-go-using-a-custom-template-ae863b65a859 作者:Michael ...

  5. Win10打补丁KB4022725出现0x80073712错误

    周末从老家回来折腾电脑,发现又收到了一大堆补丁,其中包括6月累积更新KB4022725.在安装过程中,一不小心手滑碰到了插线板,电脑断电了!!尼玛,这是要悲催的节奏么? 重新上完电开机,开机界面显示正 ...

  6. elasticsearch高级组合查询ava

    /**     * 高级检索(组合条件检索)must相当于sql and操作     * @param modelType 0为模糊查询,1为精确查询     * @param index 索引   ...

  7. win10 uwp 绑定多数据

    经常我们需要绑定的数据有多个,当添加到集合控件的对象类型结构比较复杂,我们希望自己来定义排版布局,这时可以使用ItemTemplate用资源的定义 现在有数据 public class caddres ...

  8. 【转】RAM 大全-DRAM, SRAM, SDRAM的关系与区别

    http://blog.csdn.net/huleide/article/details/5506698 ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是R ...

  9. python Logging的使用

    日志是用来记录程序在运行过程中发生的状况,在程序开发过程中添加日志模块能够帮助我们了解程序运行过程中发生了哪些事件,这些事件也有轻重之分. 根据事件的轻重可分为以下几个级别: DEBUG: 详细信息, ...

  10. 谈谈你对web标注和W3c的理解和认识

    web标准简单来说可以分为结构.表现和行为.其中结构主要是有HTML标签组成.表现即指css样式表,通过css可以是页面的结构标签更具美感.行为是指页面和用户具有一定的交互,同时页面结构或者表现发生变 ...