【问题标题】:Parallel execution with return values and async/await使用返回值和 async/await 并行执行
【发布时间】:2021-12-13 20:11:57
【问题描述】:

在 C# 中处理要同时执行的部分代码的正确方法是什么?这些调用中的每一个都需要大约 3 秒(我们目前正在我们的系统中进行索引改进)。如何使这些语句与结果并行执行?

var properties = await _propertyService.GetPropertiesAsync("Fairfax, VA");

var ratings = await _ratingsService.GetRatingsAsync(12549);

【问题讨论】:

    标签: c# .net-core async-await parallel-processing task-parallel-library


    【解决方案1】:

    您可以从调用中删除await 并等待Task.WhenAll 的结果:

    var propertiesTask = _propertyService.GetPropertiesAsync("Fairfax, VA");
    var ratingsTask = _ratingsService.GetRatingsAsync(12549);
    await Task.WhenAll(propertiesTask, ratingsTask);
    var properties = propertiesTask.Result;
    var ratings =  ratingsTask.Result;
    

    或者拆分方法调用和等待(通常是less preferable选项):

    var propertiesTask = _propertyService.GetPropertiesAsync("Fairfax, VA");
    var ratingsTask = _ratingsService.GetRatingsAsync(12549);
    var properties = await propertiesTask;
    var ratings = await ratingsTask;
    

    【讨论】:

    • 那么一种风格比另一种更有优势吗?我猜第一种方法是显式的(自我记录)。还有其他优点或缺点吗?
    • @GuruStron 省略 await Task.WhenAll 意味着如果第一个任务失败,第二个任务将作为即发即弃的任务泄露。这很少是你想要的!
    • @BuddyJoe 一个主要区别是异常处理。 Task.WhenAll 将聚合所有异常并将它们传播给调用者,而在多个 await 的情况下,只会观察到第一个错误。
    • @BuddyJoe 也可以查看this question
    【解决方案2】:

    您可以为此使用Task.WhenAll

    Task.WhenAll 不会阻塞并且可以等待,将控制权交还给调用者,直到所有任务完成(与 Task.WaitAll 相比)

    就异常而言,如果任何提供的任务在故障状态下完成,则返回的任务也将在故障状态下完成,其异常将包含来自每个提供的任务。

    var task1 = _propertyService.GetPropertiesAsync("Fairfax, VA");
    var task2 = _ratingsService.GetRatingsAsync(12549);
    
    await Task.WhenAll(task1, task2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 2020-04-06
      • 2019-05-24
      • 2021-03-15
      • 2018-06-25
      相关资源
      最近更新 更多