【问题标题】:await in Parallel.foreach [duplicate]在 Parallel.foreach 中等待 [重复]
【发布时间】:2013-04-04 16:17:12
【问题描述】:

我有一个将在 Parallel.Foreach 中使用的异步方法。在异步方法中有等待任务。 但是,在测试中,似乎没有等待行为,等待任务没有完成。有什么问题?下面是代码。

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

【问题讨论】:

  • 这是这个问题的措辞更好的问题,但它的欺骗有最好的答案:stackoverflow.com/a/11565317/176877
  • 不是这样:代码示例表明 OP 关于 async-await 和 TPL 的假设从一开始就存在缺陷,只会混淆问题。

标签: c# async-await task-parallel-library parallel.foreach


【解决方案1】:

回答晚了,但您似乎正在尝试并行执行 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
}

【讨论】:

    【解决方案2】:

    void async 方法是“一劳永逸”,没有办法等待它们完成。在您的并行循环中调用 method2 时,它会立即返回,因此您的循环仅确保在循环完成之前创建 method2 中的任务。

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

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

    你可以在循环中等待

    method2().Wait();
    

    虽然这样做并不比直接在你的 foreach 委托中运行 method2 中的任务主体更好。

    【讨论】:

    • 是的,你是对的,它有效。我必须在 method2 中运行的原因是因为我必须将不同的 Func 传递给 method1。如创建、删除等。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 2019-06-29
    相关资源
    最近更新 更多