2015-04-04 57 views
11

最近我從VB轉移到C#,所以我經常使用C#to VB.NET轉換器來理解語法差異。 雖然移動下一個方法到VB我注意到一個有趣的事情。C#++運算符是否在foreach循環中變爲線程安全?

C#原代碼:

public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools) 
{ 
    int trueCnt = 0; 
    foreach(bool b in bools) 
     if (b && (++trueCnt > threshold)) 
      return true; 
    return false;   
} 

VB.NET結果:

Public Function ExceedsThreshold(threshold As Integer, bools As IEnumerable(Of Boolean)) As Boolean 
Dim trueCnt As Integer = 0 
For Each b As Boolean In bools 
    If b AndAlso (System.Threading.Interlocked.Increment(trueCnt) > threshold) Then 
     Return True 
    End If 
Next 
Return False End Function 

C#的++運營商System.Threading.Interlocked.Increment 更換這是否意味着如果foreach循環使用的不是線程安全的++操作成爲線程?它是一種語法糖嗎?如果這是真的,那麼爲什麼轉換器在VB版本中放置Interlocked.Increment?我認爲C#和VB中的foreach完全一樣。或者它只是一個轉換器「保險」?

回答

11

我確定這只是一個轉換器黑客,我想我可以解釋這背後的推理。

但首先,爲了回答你的問題,C#中內置的++運算符不是線程安全的。它只是爲以下過程語法糖(以++i的情況下):

  • 閱讀i
  • 增量它
  • 寫回i
  • 回報增加值的價值

由於有獨立的讀寫,這是一個非原子操作。

現在,在VB中沒有直接等價於++運算符。最接近的事是:

i += 1 

這是一個聲明。相比之下,++i表達式。您可以在另一個語句或表達式中使用++i,但不能使用VB語句。

使用Interlocked.Increment只是一種巧妙的翻譯代碼的方式,無需將整個語句分解爲多個其他語句。

如果沒有這一招,轉換器將不得不打破錶達這樣的:

if (b && (++trueCnt > threshold)) 
    ... 
If b Then 
    trueCnt += 1 
    If trueCnt > threshold Then 
     ... 
    End If 
End If 

其中,你可以看到,需要更多的重寫。如果trueCnt是屬性(爲了避免兩次評估),甚至需要引入單獨的臨時變量。

這需要更深語義分析和控制流重寫比簡單句法轉換器的使用 - 只是因爲trueCnt += 1不能使用在VB中的表達。

+0

不知道是否有任何開銷,例如++與互鎖。 – 2015-04-04 18:23:10

+0

@Steve'Interlock.Increment'有點慢,因爲它引入了一個內存圍欄。但是,除非你處理非常高性能的代碼,否則這種差異不會引起注意,在這種情況下,你可能不會自動轉換它。 – 2015-04-04 18:25:38

4

我相信這是因爲您想要在比較的同一個語句中增加值。我沒有太多的理由,但它肯定是正確的答案,因爲trueCnt + = 1不允許在同一行中進行比較。它當然不是一個foreach,而是嘗試在循環外部添加相同的行,我幾乎可以肯定它也會轉換爲Increment。 VB.Net中沒有其他語法可以在同一行中進行增加和比較。

2

除了上述問題,C#的默認行爲遵循Java的不幸的整數溢出行爲。儘管有時候包裝整數溢出語義是有用的,但C#通常不會區分整數應該在溢出時換行的情況,還是整數不期望換行的情況,但程序員不認爲溢出陷阱是值得的。這可以混淆轉換工作,因爲VB.NET使陷印行爲比纏繞行爲更簡單快捷,而C#則反過來。因此,爲了速度的原因,翻譯使用未檢查數學的代碼的邏輯方法是在VB.NET中使用普通的檢查數學,而翻譯需要包裝行爲的代碼的邏輯方法是在VB.NET中使用包裝整數方法。 Threading.Interlocked.IncrementThreading.Increment.Add方法使用包裝整數行爲,所以儘管從速度角度來看它們不是最優的,但它們很方便。