等待在Parallel.foreach中

9
我有一个异步方法,将在Parallel.Foreach中使用。在异步方法中,有一个等待Task的await。 然而,在测试中,似乎没有等待行为,await Task没有完成。问题出在哪里?以下是代码。
public void method1()
{
  Ilist<string> testList = new IList<string>(){"1","2","3"};
  Parallel.ForEach(testList, ()=>
  {
       method2();
  });
}
public async void method2()
{
   await Task.run(()=>{  some other codes here });  
}

这是一个更好表述的问题,但它的重复已经有了最佳答案:https://dev59.com/aWgu5IYBdhLWcg3wHjl7#11565317 - Chris Moschini
它并不是:代码示例表明,OP对async-await和TPL的假设从一开始就存在缺陷,这只会混淆问题。 - Marc L.
2个回答

7

虽然我回答有点晚了,但是看起来你试图并行执行CPU密集型工作,而不是异步执行I/O密集型工作。 Parallel.ForEach已经处理了并行性,所以不需要使用Task.Run,async/await在这里也没有什么用处。我建议从method2中删除这些部分,使整个过程简化为:

public void method1()
{
    Ilist<string> testList = new IList<string>(){"1","2","3"};
    Parallel.ForEach(testList, ()=>
    {
        method2();
    });
}
public void method2()
{
    // some other (plain old synchronous) code here
}

3

void async方法是“发射并忘记”的,并且没有等待它们完成的方式。当在您的并行循环中调用method2时,它会立即返回,因此您的循环仅确保在循环完成之前创建了method2中的任务。

您可以将method2的返回类型更改为Task,这将允许您等待操作的结果,例如:

public async Task method()
{
     await Task.Run(() { some other code here });
}

您可以在循环中使用以下代码等待:

method2().Wait();

尽管这样做并不比直接在您的foreach委托中运行任务体的method2更好。


是的,你说得对,它有效。我必须在method2中运行的原因是我必须将不同的Func传递给method1,例如create、delete等。非常感谢。 - user1438980

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