async await 不适合实现动态并行吗?

Is async await inappropriate for achieving dynamic parallelism?

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

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

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

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

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