Является ли следующий статический метод безопасным? - PullRequest
1 голос
/ 09 февраля 2012

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

/// <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());
}

Ответы [ 2 ]

4 голосов
/ 09 февраля 2012

Вы правы.

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

3 голосов
/ 09 февраля 2012

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

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

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

...