我将一些c#代码转换为vb.net,而converter.telerik.com则将其转换为:
i--;
进入这个:
System.Math.Max(System.Threading.Interlocked.Decrement(i), i + 1)
怎么了花哨的东西?
答案 0 :(得分:10)
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 -= 1
或i = i - 1
代替someValueThatIsEqualToiMinusOne
。但是,System.Threading.Interlocked.Decrement(i)
是合法的,等于i - 1
的值。一旦这样做,因为参数是从左到右计算的,someValueThatIsEqualtoiBeforeTheDecrement
应该是i + 1
(此时已经执行到i + 1
的递减是预递减值。
请注意,上述方法DoPostDecrement
和System.Math.Max, System.Threading.Interlocked.Decrement
构造在多线程上下文中可能具有不同的语义。
答案 1 :(得分:2)
联锁操作是atomic;在多线程上下文中,如果你小心的话,你可以安全地使用它而不需要锁定。
答案 2 :(得分:0)
答案 3 :(得分:0)
这取决于 - “i”是一个共享变量吗?它是在线程安全的环境中吗?
如果“i”是一个整数,那么i--基本上做了以下(忽略细节):
如您所见,有> 1个步骤。如果“i”处于非线程安全位置(跨线程共享的静态变量等),那么线程可能会在这两个步骤的中间停止,另一个线程可以运行这两个步骤,然后你就有了数据无效的问题。
Interlocked类基本上将上述两个步骤合并为一个步骤,提供原子操作。现在您不必担心线程,因为它是单个操作,不能被另一个线程中断。
答案 4 :(得分:0)
要回答你的问题,看起来converter.telerik.com
这个问题对于线程问题过于保守。 WAAAY过于保守。如果同时没有从多个线程中突变i--
的同一个实例,我会将代码恢复为i
。