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

我将一些c#代码转换为vb.net,转换器.telerik.com转为:

i--; 

进入这个:

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

什么花哨的东西?

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

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

所以,我们需要将其转换为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构造在multithreading上下文中可能具有不同的语义。

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

我能看到的唯一原因是

Interlocked.Decrement方法

减少指定变量并将结果存储为primefaces操作。

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

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

  1. 从i中减去一个
  2. 将该值分配给i

如您所见,有> 1步。 如果“i”处于非线程安全位置(跨线程共享的静态变量等),则线程可能会在这两个步骤中间停止,另一个线程可以运行这两个步骤,然后您将拥有数据无效的问题。

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

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