gpt4 book ai didi

c# - 循环计数 != list.Count - 在新线程中填充 List

转载 作者:行者123 更新时间:2023-11-30 19:09:13 24 4
gpt4 key购买 nike

为什么以下代码的结果 (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);

最佳答案

问题是 List<T>不是线程安全的。

任务并行

您可以使用 thread-safe System.Collections.Concurrent 中的集合并使用类型 ConcurrentBag<> .尝试使用这个:

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);

还有其他线程安全类型,如 ConcurrentQueue<> , ConcurrentStack<>

处理非线程安全对象——lock(object)

另一方面,您可以使用 lock keyworkd 阻止其他线程访问同一个语句 block 。在这种情况下,您可以使用 List<T>和非线程安全对象,例如:

该对象必须对所有线程可见,因此,您可以在类范围内声明它,例如:

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);

关于c# - 循环计数 != list.Count - 在新线程中填充 List<string>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30383363/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com