使用任务并行库的帮助

3

我正在尝试使用任务并行库为一系列项目安排函数调用。

以下代码无法正常工作:

List<Task> tasks = new List<Task>();

foreach(var someValue in aCollection)
{
   var t = Task.Factory.StartNew(() => DoSomeWork(someValue));
   tasks.Add(t);
}

Task.WaitAll(tasks.ToArray());

但是以下内容可以正常工作。
Task.WaitAll(aCollection.Select(a => Task.Factory.StartNew(() => DoSomeWork(a))).ToArray());

对于第一种方法,它只执行一次,然后停止。我不确定它是否覆盖了引用或其他内容。请问有人可以解释一下吗?

另外,是否有一种方法可以向任务传递一些序列号,以便可以用于标识哪个任务最先被调度。我的意思是,我想等待所有任务完成,但然后根据集合中的顺序排序结果。


1
请参阅 http://stackoverflow.com/questions/2956328/foreach-failing-when-using-parallel-task-library/3155693#3155693。 - Jim Mischel
@Jim:谢谢。你对序列的事情有什么想法吗? - stackoverflowuser
1个回答

5

我不确定这是否导致执行停止,但也许是因为你在这里使用了循环变量的闭包

DoSomeWork(someValue));

您需要创建一个本地变量并将someValue赋值给它,然后像我链接的问题中所描述的那样使用该本地变量,具体步骤如下:

foreach(var someValue in aCollection)
{
   var localCopy = someValue;

   var t = Task.Factory.StartNew(() => DoSomeWork(localCopy));
   tasks.Add(t);
}

再次强调,我不知道这是否是死锁问题的原因,但这是最有可能会导致问题的一个问题。


是的。那就是问题所在。谢谢。+1。关于顺序的事情呢?有什么想法吗? - stackoverflowuser
1
你可以使用 for 循环与 此 Task 重载 结合使用。传递的 object 被分配给 AsyncState,它可以是任何东西,完全是任意的。在这种情况下,只需传入迭代变量 (i) 并在 WaitAll 退出时检索它即可。 - user153498
一个例子会非常有帮助。谢谢。 - stackoverflowuser
等一下,你的第二个问题,我仔细地读了一遍,你是想知道哪个任务是先“开始”的,还是哪个任务是先“结束”的? - user153498

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接