gpt4 book ai didi

c# - 添加到列表的并行循环

转载 作者:行者123 更新时间:2023-11-30 16:12:36 31 4
gpt4 key购买 nike

是否可以在循环长度增加的情况下并行化循环?

List<int> list = new List<int>() { 0, 1 };

for (int i = 0; i < list.Count; i++)
//Parallel.For(0, list.Count, (i) =>
{
Console.WriteLine(list[i]);
if (i == 0) list.Add(2);
}//);

//foreach (int i in list)
//Parallel.ForEach(list, (i) =>
//{
// Console.WriteLine(i);
// if (i == 0) list.Add(2);
//}//);

Console.ReadLine();

在这个简单的例子中,预期的输出是:

0
1
2

上面的代码对于序列号“for”可以正常工作,但对于序列号“foreach”却由于集合被修改而失败。对于这两种并行化实现,代码都已完成,但输出缺少最后的“2”。

最佳答案

在 for each 循环中更改集合是无效的。基本上以任何方式修改列表都会使枚举器无效。以下是 IEnumerator 文档中的引述:

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.

有关更多信息,请查看 this post .至于并行实现:

  • Parallel.ForEach - 这与每个标准的 IEnumerator 问题相同
  • Parallel.For - 将循环数作为常量而不是引用传递给 for。这意味着当计数发生变化时,它不会改变循环次数

更安全的模式是在调用并行实现之前添加、删除和修改列表元素。然后线程可以处理这些元素。如果无法做到这一点,则确定循环后将拥有的元素数量,然后使用数组按索引存储/处理这些元素。最后将任何非空值拉回到列表中。这样您就不必担心与列表有关的线程安全问题(Insert 会将其他元素向前推,使您的索引无效)。以下应该有效:

// EX: might be initialized with a call to the database: "COUNT(id)"
int expectedElements = 10;
if (myList.Count < expectedElements)
for (var idx = myList.Count; idx <= expectedElements; idx++) myList.Add(null);

var elements = myList.ToArray();
System.Threading.Tasks.Parallel.For(0, expectedElements, (idx) =>
{
// "remove" the element
if (idx % 3 == 0) elements[idx] = null;

// "modify" the element
if (idx % 3 == 1) elements[idx] = DifferentElement(idx);

// "add" an element
if (idx % 3 == 2) elements[idx] = GetNewElement(idx);
});

// clear current list, add new elements, remove null values
myList.Clear();
myList.AddRange(elements);
myList.RemoveAll(item => item == null);

现在您可以随心所欲地“添加”、“删除”和“修改”,结果会返回到列表中!

关于c# - 添加到列表的并行循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22713592/

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