为什么使用System.Threading.Interlocked.Decrement而不是减号?

时间:2009-12-01 20:33:29

标签: c# vb.net c#-to-vb.net

我将一些c#代码转换为vb.net,而converter.telerik.com则将其转换为:

i--;

进入这个:

System.Math.Max(System.Threading.Interlocked.Decrement(i), i + 1)

怎么了花哨的东西?

5 个答案:

答案 0 :(得分:10)

MichałPiaskowski的评论引发了以下解释:

C#中i--的语义是返回i的当前值(即递减发生前的值),然后将i递减一。

因此,我们需要将其转换为VB。我们不能使用i -= 1,因为这不会在递减之前返回i的当前值。因此,我们需要一个递减i的操作,但在递减之前返回i的值,如:

Function DoPostDecrement(ByRef i As Integer) As Integer
    i -= 1
    Return i + 1
End Function

但是这表明使用以下内容可以避免编写方法来执行上述操作:

System.Math.Max(
    someValueThatIsEqualToiMinusOne,
    someValueThatIsEqualtoiBeforeTheDecrement
)

但VB.NET不允许您使用i -= 1i = i - 1代替someValueThatIsEqualToiMinusOne。但是,System.Threading.Interlocked.Decrement(i)是合法的,等于i - 1的值。一旦这样做,因为参数是从左到右计算的,someValueThatIsEqualtoiBeforeTheDecrement应该是i + 1(此时已经执行到i + 1的递减是预递减值。

请注意,上述方法DoPostDecrementSystem.Math.Max, System.Threading.Interlocked.Decrement构造在多线程上下文中可能具有不同的语义。

答案 1 :(得分:2)

联锁操作是atomic;在多线程上下文中,如果你小心的话,你可以安全地使用它而不需要锁定。

答案 2 :(得分:0)

我能看到的唯一原因是

Interlocked.Decrement Method

  

减少指定的变量和   将结果存储为原子   操作

答案 3 :(得分:0)

这取决于 - “i”是一个共享变量吗?它是在线程安全的环境中吗?

如果“i”是一个整数,那么i--基本上做了以下(忽略细节):

  1. 从i
  2. 中减去一个
  3. 将该值分配给i
  4. 如您所见,有> 1个步骤。如果“i”处于非线程安全位置(跨线程共享的静态变量等),那么线程可能会在这两个步骤的中间停止,另一个线程可以运行这两个步骤,然后你就有了数据无效的问题。

    Interlocked类基本上将上述两个步骤合并为一个步骤,提供原子操作。现在您不必担心线程,因为它是单个操作,不能被另一个线程中断。

答案 4 :(得分:0)

要回答你的问题,看起来converter.telerik.com这个问题对于线程问题过于保守。 WAAAY过于保守。如果同时没有从多个线程中突变i--的同一个实例,我会将代码恢复为i