2016-11-24 46 views
0

我有幾個數組的類型char []和字符串[]定義爲'靜態只讀'。他們的項目從未改變。Threadsafety和與靜態只讀陣列的foreach

'foreach'和'泛型'枚舉是線程安全嗎?

private static readonly string[] staticReadOnlyArray = new string[] { "someKey0", "someKey1", "someKey2", ... }; 

public bool SomeThreadSharedCall(string toCheck) 
{ 
    // #1 
    foreach (string s in staticReadOnlyArray) 
    { 
     if (s == toCheck) 
      return true; 
    } 
    return false; 

    // #2 
    return staticReadOnlyArray.Contains(toCheck); 

    // or #3 
    return staticReadOnlyArray.Any(s => string.Compare(toCheck, s, StringComparison.OrdinalIgnoreCase) == 0); 

    // or #4 
    staticReadOnlyArray.ForEach(s => someAction(s, toCheck)); 
} 

回答

0

您的方法中的操作是「線程安全」,僅基於您的聲明Their items never change.;然而,在給定的代碼中沒有任何保證。

術語threadsafe通常用來指有問題的代碼保證,該數據不會改變,或者如果它可以變化,操作仍然會產生正確的結果。

您需要執行your own synchronization logic才能使代碼真正成爲線程安全的。

===回答您的意見:

GetEnumerator()返回值 - 你叫什麼iterator - 本身是安全的調用線程專用,但在這裏,這不是問題。它是不是線程安全的底層集合(數組),因爲它可以更改。

foreach更改爲for循環不會使代碼更安全。您需要同步對集合的訪問,或者使其不可變。

在你的情況,我建議後者給出你的數組中的數據是恆定的。爲了使它具體爲你,這裏有一些概念代碼:

private static readonly IEnumerable<string> staticReadOnlyData = Array.AsReadOnly(new string[] { "someKey0", "someKey1", "someKey2", ... }); 

public bool SomeThreadSharedCall(string toCheck) 
{ 
    // #1 
    foreach (string s in staticReadOnlyData) 
    { 
     if (s == toCheck) 
      return true; 
    } 
    return false; 

    // #2 
    return staticReadOnlyData.Contains(toCheck); 

    // or #3 
    return staticReadOnlyData.Any(s => string.Compare(toCheck, s, StringComparison.OrdinalIgnoreCase) == 0); 
} 
+0

感謝您的答覆。我清楚地理解C++上的Win32 API多線程。但我與C#4混淆。該數組是IEnumerable。對於移動它使用IEnumerator iterator = array.GetEnumerator()的引用。 那麼,是迭代器引用IEnumerator的新副本,還是每個線程都獲取對迭代器對象的一個​​副本的引用?在最後一種情況下,我們遇到了問題。 – Yargo

+0

我需要的全部 - 它是一個常量預定義數組和查找的線程安全方法。我有一個困境 - 重寫代碼從'foreach'到'for(int i = 0; i Yargo

0

如果您不確定,最好的方法就是測試它!但是,是的,它們是線程安全的。