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) и Пользователь2 выполняет FieldDataValidationManager.Validate(field2)

ответ

8

Да, ваш код является поточно-, так как ваш код только чтение из списка. Статичность или нет вообще не имеет значения.

Если бы были проблемы с записью на List<T>, у вас возникли бы проблемы с параллелизмом. Затем вы должны использовать ConcurrentBag<T> или другие типы коллекций, не связанных с потоками.

3

Проблема с параллелизмом отсутствует, если вы не меняете содержимое списка FieldRegistry.
Но вы не указали, где вы заполните этот список. Поэтому, если ваш фактический код вставляет или удаляет записи в этот список, а другие темы вызывают Validate, будут проблемы (ConcurrentBag<T>, как предложил Патрик Хофман, может быть хорошей альтернативой этому).


Но что вы на самом деле пытаетесь сделать здесь:

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

Так что, кажется, ваш fieldID является действительным, если уже есть запись с этой IDиID больше, чем 1?
OK, но ваш метод будет вызывать NullReferenceException, если fieldID еще не содержится в вашем списке. Поэтому вам лучше изменить этот метод на что-то вроде этого:

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

Дорогой Рене. Я согласен с вами, но это, к примеру. – Tim

Смежные вопросы