【问题标题】:Is the following static method thread safe?以下静态方法线程安全吗?
【发布时间】:2012-02-09 18:17:19
【问题描述】:

我今天在我们的代码库中发现了以下方法,我觉得它可能不是线程安全的。我认为 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());
}

【问题讨论】:

    标签: c# .net multithreading static thread-safety


    【解决方案1】:

    你是对的。

    该方法的实际安全性取决于你传递给它的 IEnumerable 类型;线程安全很少存在于真空中。
    例如,所有并发集合都是完全线程安全的,即使对于并发写入和枚举也是如此。

    【讨论】:

    • 感谢您的回答。这和我想的差不多。我应该采取什么方法使其在.Net 4.0 之前的线程安全?我的直接想法是要么将整个东西放在实体参数的锁中,要么将 IEnumerable 复制到列表中。不过,第二个选项假设我不在乎是否有人在我复制底层数据结构后对其进行了修改。
    • 这完全取决于你传递给方法的内容。
    • 这个方法说 T 必须是或扩展类型 LinqEntityBase。 LingEntityBase 是一个具体类,因此我们将具体类的 IEnumberable 传递给该方法。信息够不够?
    • 这根本没有任何区别。这取决于 enumerable 的实现。
    【解决方案2】:

    确实,IEnumerable entities底层数据结构很可能在其他地方被不同的线程修改,而此方法对其进行迭代。

    注意底层数据结构IEnumerable 本身不是一个具体的类,所以它可能是它背后的任何东西。

    说了这么多,方法是不是静态的没有区别,唯一的问题是所有线程是否共享entities集合。

    【讨论】:

      猜你喜欢
      • 2010-11-08
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多