.NET基础扩展系列-事件的实现原理(2)

来源:未知 责任编辑:责任编辑 发表时间:2015-03-01 01:48 点击:

  此时的NewMail 为null, newHandler 为FunctionA. 线程A停止.
 
第二步:线程B开始执行,将整个函数执行完,
  此时NewMail 为FunctionB
 
第三步:线程A继续执行, 会执行这一句: tmp = Interlocked.CompareExchange<EventHandler<EventArgs>>(ref NewMail, newHandler, prevHandler);
由于此时NewMail =FunctionB , 所以tmp 会=FunctionB ,
但由于prevHandler= FunctionA, 所以NewMail!=prevHandler, 所以NewMail保持值不变.
往下执行while (tmp != prevHandler)的判断, 就会发现tmp!=prevHandler, 就会继续循环, 直到NewMail 和prevHandler 值一样了,才会退出循环.
这样看就比较清楚, 为什么不能用Exchange了, 如果使用Exchange,那么在第三步的时候, 就会直接执行赋值, 将NewMail设置为FunctionA,那么FucntionB就不会出现在时间相应函数的委托链表中.
 
为什么CompareExchange, 就可以呢?
其实是用CompareExchange去验证线程并发控制的一个最根本的原则: 如果一个操作要被看做是不可打断的, 那么从开始到完成的真个环节中, 操作的环境不能改变.
我们随使用CompareExchange, 就可以验证NewMail 是不是我们最开始操作时候的prevHandler, 如果不是, 说明操作的基本环境已经改变, 这次操作就是无效的.
这种方式, 可以在不适用lock的情况下, 实现并发控制, 相当精妙.


摘自  Dunnice
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码:点击我更换图片
最新评论 更多>>

推荐热点

  • 浅析.NET下XML数据访问新机制
  • asp.net 面试+笔试题目第1/2页
  • C# 邮件地址是否合法的验证
  • asp.net 设置GridView的选中行的实现代码
  • C#高级编程:数据库连接[1]
  • ASP.NET&#160;GridView列表代码示例
  • 经典C++程序1
  • 微软ASP.NET站点部署指南(3):使用Web.Config文件的Transforma
  • 微软ASP.NET站点部署指南(2):部署SQL Server Compact数据库
网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索 - 移动版 - 返回顶部
Copyright © 2008-2013 计算机技术学习交流网. 版权所有

豫ICP备11007008号-1