C#内部关于绑定事件Event的线程安全
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的线程安全的更多相关文章
- 经典线程同步 事件Event
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...
- 多线程面试题系列(6):经典线程同步 事件Event
上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...
- (92)Wangdao.com_第二十五天_线程机制_H5 Web Workers 分线程任务_事件 Event
浏览器内核 支撑浏览器运行的最核心的程序 IE 浏览器内核 Trident内核,也是俗称的IE内核Chrome 浏览器内核 统称为 Chromium 内核或 ...
- C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新 使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和 ...
- {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器
Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...
- 秒杀多线程第六篇 经典线程同步 事件Event
原文地址:http://blog.csdn.net/morewindows/article/details/7445233 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权” ...
- pythonl练习笔记——threading线程中的事件Event
1 事件Event 使用方法:e = threading.Event() Event对象主要用于线程间通信,确切地说是用于主线程控制其他线程的执行. Event事件提供了三个方法:wait等待.cle ...
- 转--- 秒杀多线程第六篇 经典线程同步 事件Event
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
随机推荐
- NOIP 11.01 应试记录
快排代码 void quicksort(int left,int right) { int u,j,t,temp; if(letf>right) return; temp=a[left]; i= ...
- Web API 路由 [二] Attribute Routing
1) 启用.在App_Start - WebApiConfig.cs下 //在Register函数添加如下代码: config.MapHttpAttributeRoutes(); 2) 使用.Cont ...
- Centos7下安装php7
通过编译的方式安装php7 1. 安装PHP7 ## 下载 wget http://us2.php.net/distributions/php-7.0.2.tar.gz ## 安装 tar zxvf ...
- ASP.NET没有魔法——ASP.NET MVC 与数据库之Entity Framework Migrations
在开发数据库应用程序的时候,经常会遇到某些表需要添加字段或者修改类型.新增表等需求,而对于EF Code First来说关注的只有实体类,当需求变更时只需要添加新的实体类或者在实体类中添加.删除.修改 ...
- 在C#中实现串口通信的方法
通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围.可以访问h ...
- Golang:使用自定义模板发送邮件
https://medium.com/@itsHabib/sending-emails-with-go-using-a-custom-template-ae863b65a859 作者:Michael ...
- MySql5.7安装及配置
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS ...
- linux上redis安装配置及其防漏洞配置及其攻击方法
Linux上redis安装: 需先在服务器上安装yum(虚拟机可使用挂载的方式安装) 安装配置所需要的环境运行指令: yum -y install gcc 进入解压文件执行make 指令进行编译 执 ...
- VS中Release模式下生成去掉生成pdb文件
1.右键项目,选择属性 2.选择正确的配置,点击高级 3.调试信息选择 none,点击确定.
- win10 UWP 应用设置
win10 UWP 应用设置 简单的把设置需要的,放到微软自带的LocalSettings LocalSettings.Values可以存放几乎所有数据 如果需要存放复合数据,一个设置项是由多个值组成 ...