C#中Finally的一个不太常见的用法

原文:C#中Finally的一个不太常见的用法

最近在看.net BCL 传送门 的源码. 在

System.Collections.Concurrent.ConcurrentQueue

中看到一段有意思的代码.注意这段代码是写在ConcurrentQueue这个用于并发中的队列. 注意,这是一个无锁队列的实现.

   try
    { }
    finally
    {
        newhigh = Interlocked.Increment(ref m_high);
        if (newhigh <= SEGMENT_SIZE - 1)
        {
            m_array[newhigh] = value;
            m_state[newhigh].m_value = true;
        }
        if (newhigh == SEGMENT_SIZE - 1)
        {
            Grow();
        }
    }

  

 

有意思吗?代码中使用了一个空的Try代码块.然后把代码全都写在了Finally块.这么做的目地何在呢?

这其实是一个小的技巧:放在Finally中的代码可以防止执行线程在执行过程中被另一个线程用调用了Thread.Abort()或Thread. Interrupt()打断.从而保证这段代码执行的完整性.

举个例子: 如果不将上面代码放到Finally中运行.假如正好有一个线程A执行到 m_array[newhigh] = value;而另外一个线程B调用了线程A的Thread.Abort() 那么m_array[newhigh] = value; 以后的代码可能没有机会得到执行.那么将引起ConcurrentQueue的不完整.

而放到Finally中的代码,即使线程B在线程A执行时调用了Thread.Abort()或Thread. Interrupt()方法时也能保证Finally块中的代码被完整的执行.

事实上,这个特性是在.net framework2.0中引入的.在.net 1.1时Finally没有这个作用.另外 Tread.Abort有可能打断线程内的静态构构函数执行.

另外我认为同样的功能也可以用这个Thread.BeginCriticalRegion 和Thread.EndCriticalRegion(); 来实现.

 

时间: 2024-10-22 01:43:37

C#中Finally的一个不太常见的用法的相关文章

Shell中if的基本语法和常见判断用法

  这篇文章主要介绍了Shell中if的基本语法和常见判断用法,本文讲解了if的基本语法.对字符串的判断.对数字的判断.对文件属性的判断.逻辑判断等内容,需要的朋友可以参考下 if, for, while几乎是所有编程语言的关键字,在Shell编程中也不例外,其中if是使用频率最高的,由于Shell编程中不存在对象(Object)的概念,因此在if的比较判断中主要是对字符串.数字的值进行比较判断的: 一. if的基本语法 1.if与[之间要有空格 2.[]与判断条件之间也必须有空格 3.]与;之

Shell中if的基本语法和常见判断用法_linux shell

if, for, while几乎是所有编程语言的关键字,在Shell编程中也不例外,其中if是使用频率最高的,由于Shell编程中不存在对象(Object)的概念,因此在if的比较判断中主要是对字符串.数字的值进行比较判断的: 一. if的基本语法 1.if与[之间要有空格 2.[]与判断条件之间也必须有空格 3.]与;之间不能有空格 二. 对字符串的判断 1.if [ str1=str2 ];then fi #当两个字符串相同时返回真 2.if [ str1!=str2 ];then fi #

c++的问题-c++中int是一个类么,c++中int是一个类么,取大神,取大神

问题描述 c++中int是一个类么,c++中int是一个类么,取大神,取大神 c++中int是一个类么,取大神,取大神,c++中int是一个类么,取大神,取大神,c++中int是一个类么,取大神,取大神 解决方案 int是基本类型,不是类.C++也不是完全面向对象的语言. 解决方案二: 不是-------- 解决方案三: 不是的哦,只是基本类型而已 解决方案四: int不是一个类.int是一种数据类型.数据类型就是固定内存大小的别名.int占四个字节.所以你定义一个int型变量,他占四个字节.

c语言中怎么把一个大小不确定的二维数组当作参数传入函数中

问题描述 c语言中怎么把一个大小不确定的二维数组当作参数传入函数中 c语言中怎么把一个大小不确定的二维数组当作参数传入函数中,取大神,取大神,取大神 解决方案 用VC++新建一个程序,默认生成的main函数定义如下 int mian(int argc, char* args[]) 这就是一个例子. 解决方案二: 一个表示长度的参数,一个指向二维数组的指针 解决方案三: fun(args[][],int rows,int cols) 解决方案四: void Func(int array[][10]

图片压缩-如何判断一个JPEG2000的文件中的每一个packet?

问题描述 如何判断一个JPEG2000的文件中的每一个packet? 最近在研究JPEG2000的图像格式,我发现一个问题.现在到这里来问问一下大神. 从理论上将,JPEG2000的image只要一些最基本的数据不丢失的话,其它部分的数据丢失的话,是不会影响太大的(除了resolution和qunlity的). 但是现在我想知道的问题是,我手头里有一个JPEG2000的格式的文件,我该如何知道它的哪一部分的数据是可以丢掉的啊? 解决方案 http://wenku.baidu.com/link?u

如何能在微信中内嵌一个web页面

问题描述 如何能在微信中内嵌一个web页面 想问一下如何能在微信公众平台中内嵌一个web页面呢?具体方向是什么呢?本人对这个不太懂.想咨询一下

win7电脑中突然出现一个本地磁盘Q怎么办?

  一般说来,在w764位旗舰版中,咱们本地磁盘都是c.d.e.f盘组成的,即便是有U盘或者是硬盘的介入,一般也会用H.K.G等符号来命名,而且从另一个层面来说,咱们本地磁盘一般不会太多,因为分出过多的磁盘会导致每个硬盘的容量过少,不方便存储数据,不过最近有的朋友却在w764位旗舰版中发现了一个奇怪的现在,不知道为什么,本地磁盘中就莫名其妙的出现了一个本地磁盘Q,而且该磁盘是无法正常访问的,这是什么原因导致的,咱们又要如何删除掉这个磁盘呢? 首先,咱们先分析一下出现这种情况的原因:一般来说,出现

CAXA中怎么画一个球体?

CAXA中怎么画一个球体?   1.双击运行程序; 2.弹出对话框按确定键; 3.新建A3图框; 4.选择圆形工具绘制一个直径50的圆; 5.选择正交,然后按照图示复制出2个圆; 6.选择标注,标注后我们发现标注的字体太小了,这时候我们可以按照下个步骤进行修改

开机出现服务器正在运行中由于另一个程序正在运行中怎么办?

  为什么开机后就出现"服务器正在运行中由于另一个程序正在运行中,此操作无法完成.请选择"切换到"来激活正在运行中的程序,并更正问题",需要点击多次"切换到"才能使这个对话框消失,电脑也不能进入正常的运行,奇怪了,今天小编就自己的亲身经历来交大家如何解决. 1.crtl+alt+del调用windows任务管理器 2.然后,文件-新建任务运行 3.输入msconfig.msc 4.然后禁用里面的所有开机启动项 5.接着重启一下电脑,启动起来时候就