【问题标题】:Is async await inappropriate for achieving dynamic parallelism?async await 是否不适合实现动态并行?
【发布时间】:2019-11-19 06:47:21
【问题描述】:

我正在编写一个将在 ASP.NET Core (2.2) 上运行的服务。在请求/响应的上下文中执行的工作是高度 CPU 密集型的,并且不依赖于 I/O 或其他基于网络的服务。由于正在执行的工作的性质,动态并行似乎是最好的方法。这不是调用 Parallel.ForEach 的问题,而是根据需要创建和运行任务。

这就是背景。我没有弄清楚的是: 使用等待异步模式有优点还是缺点?我可以创建任务并使用诸如 Task.WaitAll 和 Task.WaitAny 之类的阻塞调用来等待它们,或者我可以创建任务并使用诸如 Task.WhenAll 和 Task.WhenAny 之类的非阻塞调用来等待它们。

我在各种网站上看到了使用 Task.Wait* 方法来实现动态并行性的建议(尤其是在 Stephen Cleary 的书“C# Cookbook 中的并发”,第 3.4 章),但我不太明白为什么.在进行动态并行时使用阻塞调用有固有的优势吗? async/await 方法在等待被调用任务完成时释放调用任务,难道不是提供自己的优势吗?

【问题讨论】:

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


    【解决方案1】:

    动态并行性早于asyncawait,它通常在需要阻塞的部分代码中完成,但您可以 await 一个CPU 密集型任务,就像你可以await 一个 I/O-bound 任务。

    根据我的经验,大多数时候动态并行使用AttachedToParent,这让任务隐含地等待其所有子项。不是真正的Wait,因为线程没有被阻塞,而是更多await 风格的Wait。出于这个原因,我没有在我的动态并行代码中明确使用await。但如果您不想阻塞调用线程,通常会有一个顶级await

    【讨论】:

    • 好的。这就说得通了。我采用的方法不会使用 AttachedToParent,
    • 在上面的评论中不小心按了“Enter”....好的。这就说得通了。我采用的方法不会使用 AttachedToParent。相反,我创建了很多任务(通常比 CPU 更多的任务),其中任务必须等待“预计算”任务完成,然后才能进行自己的计算。这导致我采用等待/异步方法。鉴于这种设置,我从您那里听到的是,以这种方式等待 CPU 密集型任务应该不是问题。对吗?
    • 另一种选择是自行管理任务。我并不是说要制作一个完整的任务调度程序,而是利用 .net infoworld.com/article/3152735/… 提供的任务工具
    • 如果您不使用AttachedToParent,您可以使用awaitContinueWith 让一项任务依赖于另一项任务。我不确定在这种情况下哪个会更好,但如果你混合使用它们,请特别注意包装的任务(例如,Task<Task>)。
    猜你喜欢
    • 2019-02-27
    • 2020-09-25
    • 2013-06-20
    • 2018-11-06
    • 1970-01-01
    • 2020-03-26
    • 2019-09-22
    • 1970-01-01
    • 2018-03-24
    相关资源
    最近更新 更多