2016-03-29 4 views
3

私はクラスの下にありますこの静的メソッドはスレッドセーフですか?

public static class MetadataManager 
{ 
    // assume that it is thread safe 
    public static List<Field> FieldRegistry { get; set; } 
} 

public class Field 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 



public static class FieldDataValidationManager 
{ 
    public static bool Validate(int fieldID) 
    { 
     return MetadataManager.FieldRegistry.FirstOrDefault(f => f.ID == fieldID).ID > 1; 
    } 

    public static bool Validate(Field field) 
    { 
     return fieldID.ID > 1; 
    } 
} 

、 User1とUser2が同時に静的メソッドを呼び出して、同時性に関するいかなる問題があるのでしょうか?

FieldDataValidationManager.Validate(111) 

または User1が FieldDataValidationManager.Validate(field1)を実行しているとUser2があなたのコードだけで、リストから読んでいるので、はい、あなたのコードは、スレッドセーフであるFieldDataValidationManager.Validate(field2)

答えて

8

を実行しています。静的であるかどうかは問題ではありません。

List<T>に書き込みアクションがあると、並行性の問題が発生する可能性があります。次に、ConcurrentBag<T>またはその他のスレッドセーフなコレクションタイプを使用する必要があります。

3

FieldRegistryリストの内容を変更しない限り、並行性の問題はありません。
しかし、あなたはそのリストをどこに記入したのかわかりませんでした。したがって、実際のコードが他のスレッドがValidateを呼び出している間にそのリストにエントリを挿入または削除した場合は、問題が発生します(Patrick Hofmanの提案によるとConcurrentBag<T>)。


しかし、あなたが実際にここでやろうとしている。

public static bool Validate(int fieldID) 
{ 
    return MetadataManager.FieldRegistry.FirstOrDefault(f => f.ID == fieldID).ID > 1; 
} 

だから、そのIDのエントリID1よりも大きいがすでにある場合は、あなたのfieldIDが有効であると思われますか?
fieldIDがあなたのリストにまだ含まれていない場合、あなたのメソッドはNullReferenceExceptionを投げます。したがって、この方法を次のように変更するとよいでしょう。

public static bool Validate(int fieldID) 
{   
    return 
     MetadataManager.FieldRegistry.Any(f => f.ID == fieldID) && 
     fieldID > 1; 
} 
+0

親愛なるルネ。私はあなたに同意しますが、それは単なる例です。 – Tim

関連する問題