今天偶然看到一段代码,也看到了作者对此的说明,觉得很有意思:
public eventEventHandler Started;

protected virtual voidOnStarted(EventArgs e)
{
    EventHandler handler =Started;
    if(handler != null)
    {
        handler(null, e);
    }
}

为什么要申明一个全局的事件变量 Started?一开始我也觉得很多余,后来听作者说这段代码可以用到多线程中,有可能正在判断事件变量Started的时候,它有可能被另外的一个线程给改变了,这里引入一个局部变量 handler,可以保留Started之前的对象引用,确保后面的事件能够得到正确的处理。

那么我们是否可以按照这个风格写下面类似的代码呢?

public object MyObject;

public  void OnFunction()
{
    object obj= MyObject;
    if (obj!= null)
    {
        //在这里对obj进行其它处理

}
}

上面这段代码在一般情况下没有问题,在多线程下面也工作良好,但如果你启用了编译器优化,很不幸,这段代码被优化成了下面的样子:

public object MyObject;

public  void OnFunction()
{
    if (MyObject!= null)
    {
        //在这里对MyObject进行其它处理

}
}

也就是说,MyObject 对象引用的代码被inline(内联)了,取消了局部变量object obj的定义,减少了对象数量和创建过程,有助于提高效率,如果这段代码被用于多线程中,噩梦很可能就来了,你不知道是谁修改了MyObject的值,这就是“编译器陷阱”!

类似的代码,为什么上面EventHandler Started 在多线程下工作的很好,而object MyObject 却不可以?原来,这其中有玄机,在.NET平台中,它采用了不同的优化策略,参加原博文中的说法:

如果我说,这样的代码明显是会被编译器优化掉的,因此这样写完全没有意义,怎样呢?毕竟EventHandler作为一个委托,并没有用volatile关键字声明(事实上事件不能声明为volatile,但可以在这里用Thread.VolatileRead(ref object)方法),使用时也没有用Interlocked来访问。我其实真没有想到那么远,不过CLR Via C#上给出了解释(记不得是哪一章了):JIT的编译器在这里会识别出这个写法并且确保不会把handler变量优化掉。真是万幸,但估计又成为了一个被学院派的诟病的特性。

原文地址:

再说说C#定义事件的写法

浅议“全局变量”、“多线程”和“编译器陷阱”相关推荐

  1. c语言指针转换成数组,浅议C语言中灵魂数组和指针的互操作(转)

    浅议C语言中灵魂数组和指针的互操作(转)[@more@]曾听好多朋友说,C是一种怀旧的语言,因为它的历史很久远,然而自从各种面向对象的编程语言的相续出现让它的影响力日减. 当然了,这是无可非议的,但是 ...

  2. 原创 | 浅议个人数据开发利用新范式

    在所有数据资产类型中,个人数据的开发利用潜在价值巨大.个人数据在过去几十年里,已经得到前所未有的开发和利用,推动了经济增长和社会发展.但与此同时,也逐渐引发越来越凸出的经济.社会和伦理道德问题. Ap ...

  3. 原创 | 浅议数据资产市场

    培育和发展数据要素市场已经成为当前和今后一段时期的重要课题.针对数据资产确权.定价以及数据市场规则.制度以及新型数据市场基础设施的研究也非常活跃. 本文拟从微观的视角,就数据资产如何形成.交易以及数据 ...

  4. 浅议DAS、NAS、SAN三种存储架构

    浅议DAS.NAS.SAN三种存储架构 目前磁盘存储市场上,存储分类(如下表一)根据服务器类型分为:封闭系统的存储和开放系统的存储,封闭系统主要指大型机,AS400等服务器,开放系统指基于包括Wind ...

  5. [CS101] 转载:浅议Fibonacci(斐波纳契)数列求解

    原文转载自林健随笔的"浅议Fibonacci(斐波纳契)数列求解" Fibonacci 数列 描述了动物繁殖数量.植物花序变化等自然规律.作为一个经典的数学问题,Fibonacci ...

  6. 浅议C#客户端和服务端通信的几种方法:Rest和GRPC和其他

    本文来自:https://michaelscodingspot.com/rest-vs-grpc-for-asp-net/ 浅议C#客户端和服务端通信的几种方法:Rest和GRPC 在C#客户端和C# ...

  7. 对计算机基础知识的一点感想,浅议对《计算机应用基础》教学感想.doc

    浅议对<计算机应用基础>教学感想 浅议对<计算机应用基础>教学感想摘要:针对计算机文化基础课程改革实践中存在的某些问题,文章总结了在课程体系.教学内容.教学方法.教学手段及教学 ...

  8. 网络语音视频技术浅议(附多个demo源码下载)

    我们在开发实践中常常会涉及到网络语音视频技术.诸如即时通讯.视频会议.远程医疗.远程教育.网络监控等等,这些网络多媒体应用系统都离不开网络语音视频技术.本人才疏学浅,对于网络语音视频技术也仅仅是略知皮 ...

  9. 浅议初中语文微写作(语文教师论文)

    浅议初中语文微写作 前言: 从汉字源流来看,"微"字引申为"细微的""精妙.深奥的"等,从"微"字的释义来看,可以对&q ...

最新文章

  1. waf可以查看post请求吗_WAFNinja:一款绕过WAF的渗透工具
  2. unity 实现手机振动_Unity 手机震动插件Vibration
  3. 谷歌 MapReduce 初探
  4. .NET Core开发实战(第8课:配置框架:让服务无缝适应各种环境)--学习笔记
  5. 国内各大平台的推荐算法,看到360的时候笑喷了……
  6. 光端机的原理和使用范围
  7. 强化学习扫盲贴:从Q-learning到DQN
  8. 199. Binary Tree Right Side View
  9. C++之=deleted
  10. word中如何替换一些特殊符号
  11. CS系统设计与开发——人事档案管理系统的设计与实现
  12. WLAN从入门到精通-1
  13. 请教dalao,为什么运行时二三步会合并到一起?
  14. 记一次触发器定义者不同导致的sql异常TRIGGER command denied to user 'XXX' @'%' for table '...
  15. js数组格式转成json格式
  16. 2015 中国电商网站排行榜
  17. Thinkphp 5.1 PC和手机端加载不同路径下的模板~功能实现
  18. 牛客网嵌入式开发面试集合(更新中....)
  19. C语言文件操作实例代码
  20. 淘淘商城第32讲——CMS内容管理系统的搭建

热门文章

  1. 在不推动提交的情况下触发Travis-CI重建?
  2. 使用Python迭代字符串中的每个字符
  3. Linux编程训练网站,OK6410汇编程序练习
  4. MTK:GPIO的配置与接口说明
  5. 服务器导流板的作用,前保险杠下导流板的作用是什么?
  6. c 语言 循环判断语句,C值循环语句(七)
  7. 洛谷——P1009 [NOIP1998 普及组] 阶乘之和
  8. 背景半透明(HTML、CSS)
  9. 使用DQL查询数据(重点)
  10. PTA-Hello World(C语言)