2012-02-09 4 views
1

Я нашел следующий метод в нашей базе кода сегодня, и мне кажется, что он может быть небезопасным. Я думаю, что IEnumerable может быть ссылочным типом и потенциально может быть изменен другим потоком, пока выполняется этот код. Верно ли это, или этот метод является поточно-безопасным? Если нет, целесообразно ли для этого метода быть статическим? Похоже, что создание метода экземпляра не изменило бы возможность изменения параметра сущностей в другом потоке.Является ли следующий поток статического метода безопасным?

/// <summary> 
/// Writes the Entity data in <paramref name="entities"/> to a CSV file located at <paramref name="path"/>. 
/// </summary> 
/// <typeparam name="T">The Entity Type.</typeparam> 
/// <param name="entities">A List of Type LinqEntityBase.</param> 
/// <param name="path">The location of the CSV file.</param> 
internal static void LinqEntitiesToCsv<T>(IEnumerable<T> entities, string path) where T : LinqEntityBase 
{ 
    var entityBuilder = new StringBuilder(); 
    List<KeyValuePair<string, int>> columnInfos = GetColumnInfos<T>(); 
    for (int i = 0; i < columnInfos.Count; i++) 
    { 
     string columnName = columnInfos[i].Key; 
     entityBuilder.Append(columnName.Contains(',') ? columnName.WrapIn('\"') : columnName); 
     entityBuilder.Append(i < columnInfos.Count - 1 ? "," : string.Empty); 
    } 

    entityBuilder.Append(Environment.NewLine); 

    PropertyInfo[] propertyInfos = typeof (T).GetPropertiesFromCache().ToArray(); 
    foreach (T entity in entities) 
    { 
     for (int i = 0; i < propertyInfos.Length; i++) 
     { 
      var columnAttribute = Attribute 
             .GetCustomAttribute(propertyInfos[i], typeof (ColumnAttribute)) 
            as ColumnAttribute; 
      if (columnAttribute == null) 
      { 
       continue; 
      } 

      object value = propertyInfos[i].GetValue(entity, null); 
      string valueString = (value != null) ? value.ToString() : string.Empty; 

      entityBuilder.Append(valueString.Contains(',') ? valueString.WrapIn('\"') : valueString); 
      entityBuilder.Append(i < columnInfos.Count - 1 ? "," : string.Empty); 
     } 

     entityBuilder.Append(Environment.NewLine); 
    } 

    FileHelper.TryWriteTextFile(path, entityBuilder.ToString()); 
} 

ответ

4

Вы правы.

Фактическая безопасность метода зависит от того, какой вы тип IEnumerable, который вы передаете; безопасность потока редко существует в вакууме.
Например, все параллельные коллекции полностью поточно-безопасные, даже для одновременной записи и перечисления.

+0

Спасибо за ответ. Это в значительной степени то, что я думал. Какой подход следует использовать для обеспечения безопасности потока в pre. Net 4.0? Я сразу же подумал, что либо поставить все это внутри блокировки на параметр сущности, либо скопировать IEnumerable в список. Второй вариант делает предположение, что меня не волнует, если кто-то модифицирует базовую структуру данных после того, как я ее скопирую. –

+1

Это полностью зависит от того, что вы передаете методу. – SLaks

+0

Этот метод говорит, что T должен быть или расширять тип LinqEntityBase. LingEntityBase - это конкретный класс, поэтому мы передаем методу IEnumberable конкретных классов. Это достаточно информации? –

3

Действительно, вполне возможно, что в другом месте базовая структура данных из IEnumerable entities изменяется другим тегом, пока этот метод выполняет итерацию по нему.

Обратите внимание на базовые структуры данных. IEnumerable сам по себе не является конкретным классом, поэтому он может быть чем-то позади.

Сказав это, является ли метод статическим или нет, не имеет значения, единственный вопрос заключается в том, имеют ли все потоки коллекцию entities.

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