【问题标题】:multiple parallel async calls with await带有等待的多个并行异步调用
【发布时间】:2011-05-12 07:21:12
【问题描述】:

据我所知,当运行时遇到下面的语句时,它会将函数的其余部分包装为异步调用的方法的回调(在此示例中为 someCall())。在这种情况下,anotherCall() 将作为对someCall() 的回调执行:

    await someCall();
    await anotherCall();

我想知道是否可以让运行时像这样执行:以异步方式调用 someCall() 并立即返回到调用线程,然后类似地调用 anotherCall()(无需等待 someCall 完成)。因为我需要这两种方法异步运行,并假设这些调用只是触发和忘记调用。

是否可以只使用asyncawait 来实现这个场景(不使用旧的begin/end 机制)?

【问题讨论】:

    标签: asynchronous multitasking async-await c#-5.0


    【解决方案1】:

    async/await 包含一些有助于并行组合的运算符,例如 WhenAllWhenAny

    var taskA = someCall(); // Note: no await
    var taskB = anotherCall(); // Note: no await
    
    // Wait for both tasks to complete.
    await Task.WhenAll(taskA, taskB);
    
    // Retrieve the results.
    var resultA = taskA.Result;
    var resultB = taskB.Result;
    

    【讨论】:

    • EcmaScript / Javascript 有这些吗?
    • @Azteca:当然,您可以使用Promise.all 代替Task.WhenAll,或使用Promise.race 代替Task.WhenAny。例如,await Promise.all([promiseA, promiseB]);
    【解决方案2】:

    最简单的方法可能是这样做:

    var taskA = someCall();
    var taskB = someOtherCall();
    await taskA;
    await taskB;
    

    如果你想要结果值,这特别好:

    var result = await taskA + await taskB;
    

    所以你不需要taskA.Result

    TaskEx.WhenAll 可能比两个之后的等待要快。我不知道,因为我还没有对此进行性能调查,但是除非您发现问题,否则我认为连续两次等待会更好,尤其是在您想要结果值的情况下。

    【讨论】:

    • 引用“C# 5.0 中的异步”:“这是等待多个任务的危险方式,如果它们可能抛出异常。如果两个操作都抛出异常,则第一个 await 将传播其异常,这意味着永远不会等待taskB。不会观察到它的异常,并且根据 .NET 版本和设置,可能会丢失甚至在意外线程上重新抛出,从而终止进程。”
    • 所以你最好坚持await Task.WhenAll(taskA, taskB);
    【解决方案3】:

    如果您使用的是 .NET 4.5,则不再需要 Async CTP。请注意,异步功能由编译器实现,因此 .NET 4 应用程序可以使用它,但需要 VS2012 来编译它。

    不再需要TaskEx。 CTP 无法修改现有框架,因此它使用扩展来完成该语言在 5.0 中可以处理的事情。直接使用Task即可。

    因此,我重写了代码(由 Stephen Cleary 回答),将 TaskEx 替换为 Task。

    var taskA = someCall(); // Note: no await
    var taskB = anotherCall(); // Note: no await
    
    // Wait for both tasks to complete.
    await Task.WhenAll(taskA, taskB);
    
    // Retrieve the results.
    var resultA = taskA.Result;
    var resultB = taskB.Result;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-03
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2017-03-31
      相关资源
      最近更新 更多