C# 循环计数!=list.Count-填充列表<;字符串>;以新的思路

C# 循环计数!=list.Count-填充列表<;字符串>;以新的思路,c#,asynchronous,C#,Asynchronous,为什么下面代码的结果(list.Count)总是在18100左右,而不是预期的19000 var list = new List<string>(19000); List<Task> tl = new List<Task>(19000); for (int q = 0; q < 19000; q++) { tl.Add(Task.Factory.StartNew(() => {

为什么下面代码的结果(list.Count)总是在18100左右,而不是预期的19000

    var list = new List<string>(19000);
    List<Task> tl = new List<Task>(19000);

    for (int q = 0; q < 19000; q++)
    {
        tl.Add(Task.Factory.StartNew(() =>
        {
            var k = "something";
            list.Add(k);
        }));
    }

    Task.WaitAll(tl.ToArray());
    Console.WriteLine(list.Count);
var列表=新列表(19000);
列表tl=新列表(19000);
对于(int q=0;q<19000;q++)
{
tl.Add(Task.Factory.StartNew(()=>
{
var k=“某物”;
增加(k);
}));
}
Task.WaitAll(tl.ToArray());
Console.WriteLine(list.Count);
列表类不是线程安全的,请参见

线程安全 此类型的公共静态(在Visual Basic中共享)成员是线程安全的。任何实例成员都不能保证线程安全


对一个列表执行多个读取操作是安全的,但如果在读取集合时对其进行修改,则可能会出现问题。为确保线程安全,请在读或写操作期间锁定集合。要使集合能够由多个线程访问以进行读写,必须实现自己的同步。有关内置同步的集合,请参阅System.collections.Concurrent命名空间中的类。对于固有的线程安全替代方案,请参见ImmutableList类。

问题在于
列表
不是线程安全的

任务并行性 您可以在中使用集合并使用类型。尝试使用以下方法:

var list = new ConcurrentBag<string>();

List<Task> tl = new List<Task>(19000);

for (int q = 0; q < 19000; q++)
{
    tl.Add(Task.Factory.StartNew(() =>
    {
        var k = "something";
        list.Add(k);
    }));
}

Task.WaitAll(tl.ToArray());
Console.WriteLine(list.Count);
之后,在需要修改时尝试锁定此实例,例如:

private static object _sync = new object();
var list = new List<string>(19000);

List<Task> tl = new List<Task>(19000);

for (int q = 0; q < 19000; q++)
{
    tl.Add(Task.Factory.StartNew(() =>
    {
       lock(_sync)
       {
          var k = "something";
          list.Add(k);
       }
    }));
}

Task.WaitAll(tl.ToArray());
Console.WriteLine(list.Count);
var列表=新列表(19000);
列表tl=新列表(19000);
对于(int q=0;q<19000;q++)
{
tl.Add(Task.Factory.StartNew(()=>
{
锁定(同步)
{
var k=“某物”;
增加(k);
}
}));
}
Task.WaitAll(tl.ToArray());
Console.WriteLine(list.Count);
列表(T)
不是线程安全的

此类型的公共静态成员是线程安全的。任何情况 不能保证成员是线程安全的


因此,从多个线程分配给它的结果不能保证产生所需的结果。

列表
不是线程安全的。你不能这么做。所以我必须实现锁定一个单独的类,该类包含对该列表的访问,对吗?@Legends这样做是没有意义的。你只需要序列化所有的东西,结果它会做更多的工作。解决方法是首先不要并行化它。这是否意味着,如果我将列表设置为静态
static list=new list()它应该工作吗?我试过了,但不起作用。不,它指的是List(t)类的静态成员,与您的问题无关。当您从多个线程访问列表时,应该使用Felipe Oriani建议的并发集合进行多线程。创建一整组线程来执行工作,然后将它们全部同步,这样就不会有多个线程可以执行任何工作,这实际上是徒劳的。问题的解决方案不是一个锁,而是首先不要并行化工作。