2016-11-24 6 views
0

「静的読取り専用」として定義されたchar []とstring []型の配列がいくつかあります。彼らのアイテムは決して変化しません。静的読取り専用配列のスレッドセーフとforeach

'foreach'と 'generics'列挙型はスレッドセーフですか?

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

ありがとうございます。私はWin32 APIのマルチスレッド化をC++ではっきりと理解しています。しかし、私はC#4と混同しています。配列はIEnumerableです。移動の場合は、IEnumerator iterator = array.GetEnumerator()の参照を使用します。 IEnumerator の新しいコピーを参照するイテレータか、または各スレッドがイテレータオブジェクトの1つのコピーへの参照を取得していますか?最後のケースでは問題があります。 – Yargo

+0

私が必要とするのは、常に定義済みの配列で、検索のためのスレッドセーフなメソッドです。私は「foreach」から「for(int i = 0; i Yargo

0

よくわからない場合は、テストしてください。しかし、はい、スレッドセーフです。

関連する問題