如果两个引用尝试在List <t> colletion </t>中完全相同地添加数据,会发生什么

时间:2012-02-29 02:03:46

标签: c# list c#-4.0 collections

检查此功能。

private static IEnumerable<string> FindAccessibleDatabases()
{
    var connectionStrings = new List<string>();
    Parallel.For(0, _connectionStringCollection.Count, (index, loopState) =>
    {
        try
        {
            using (var connection = new OleDbConnection(_connectionStringCollection[index]))
            {
                connection.Open();
                connectionStrings.Add(_connectionStringCollection[index]);
            }
        }
        catch (OleDbException)
        {
        }
        finally         
        {
           connection.Close();
        }
    });
    return connectionStrings.ToList();
}

我正在使用Parallel.Foreach并一次从多个数据库中添加List中的值。我可以使用ConcurrentBag(它在检索数据时是安全的,但是没有提到添加),因为我只是将数据添加到列表中,可以使用List。

现在,如果两个线程试图在同一时间将数据添加到列表中会发生什么?

如果它会创建竞争条件,如果我使用ConcurrentBag怎么办?

谢谢, OMKAR

1 个答案:

答案 0 :(得分:5)

您可能会发生未指定的错误的风险,例如重复项,未添加的项目,损坏数据结构等。

The documentationList<T>的Add方法不是线程安全的(具体来说,它说:

  

List<T>可以同时支持多个读者,只要   集合未被修改。列举一个集合是   本质上不是一个线程安全的程序。在罕见的情况下   枚举与一个或多个写访问争用,唯一的方法   确保线程安全是在整个过程中锁定集合   列举。允许多个访问集合   阅读和写作的线程,你必须实现自己的   同步。

)。因此,您需要在其周围使用lock statement或其他形式的线程同步,或者您需要切换到线程安全的数据结构,就像System.Collections.Concurrent命名空间中的某些内容一样。

如果使用ConcurrentBag的Add方法,则无需担心锁定。数据结构明确是线程安全的。