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

om4*_*987 0 c# collections list c#-4.0

检查此功能.

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢,Omkar

Chr*_*ain 5

您冒着发生未指定的不良事件的风险,例如重复,没有添加一个项目,破坏数据结构等.

文档说,List<T>Add方法不是线程安全的(好吧,特别是它说:

A List<T>可以同时支持多个读取器,只要不修改集合即可.枚举通过集合本质上不是线程安全的过程.在枚举与一个或多个写访问争用的极少数情况下,确保线程安全的唯一方法是在整个枚举期间锁定集合.要允许多个线程访问集合以进行读写,您必须实现自己的同步.

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

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