【问题标题】:Using .Net Parallel Extensions (Parallel.Invoke) for multiple asynchronous calls?使用 .Net 并行扩展 (Parallel.Invoke) 进行多个异步调用?
【发布时间】:2010-09-14 22:59:19
【问题描述】:

目前,我有一段代码需要对各种数据提供者进行大约 7 次 Web 服务调用。每个调用都需要几秒钟的时间来执行,所以我想并行运行它们以加快速度。

我已经将我的 7 个调用封装在 Parallel.Invoke 中,它非常适合同时运行几件事情,但在 2 核服务器上,它一次只能执行 2 个,每个内核一个。由于我所做的只是等待 Web 服务调用返回,因此我希望它获取所有 7 个并等待它们返回。

有没有办法做到这一点?或者也许我的方法是错误的?也许我需要创建对 Web 服务的异步调用?但是如何等他们都回来再继续前进呢?

【问题讨论】:

    标签: .net asynchronous parallel-extensions


    【解决方案1】:

    但在 2 核服务器上,它一次只能执行 2 个,每个核心一个

    我会质疑这一点 - Parallel.Invoke 通常会运行比系统中的内核更多的任务。

    话虽如此,如果您使用异步方法调用调用,我建议您使用Task.Factory.FromAsync(...) 来生成您的七个不同任务。

    这提供了在任务执行时执行其他工作的灵活性,然后在您决定使用结果时调用Task.WaitAll(或Task.WaitAny)。

    另一方面,Parallel.Invoke 将始终阻塞,直到所有七个完成。

    【讨论】:

    • 我的印象是他确实希望所有这些都完成后再继续。
    • @Steven:他可以通过 Task.WaitAll 完成 - 但他可以在等待时做其他工作,如果有的话,如果这是一个选项。但是,像这样的情况通常与 Task.WaitAny 一起使用,因为您通常可以在某些任务完成后立即开始一些工作 - 很少需要 7 个不同的结果来进行任何处理...
    • 你说得对,这也可以,而且比我建议的更灵活。
    • 感谢您的信息。请问..是创建几个任务然后使用 Task.WaitAll 只是 Parallel.Invoke 的语法糖吗?
    • @puffpio:不完全——Parallel.Invoke 不允许返回(任务实际上可以将代表的返回值视为期货),并且在何时以及如何处理方面具有更大的灵活性等待。如果 Task 对象不是 Task,并且您只是立即执行 Task.WaitAll,那么它的行为将类似于 Parallel.Invoke。
    【解决方案2】:

    没有必要为此使用Parallel.Invoke。您可以继续发出多个异步请求(即HttpWebRequest.BeginGetResponse())。至于在它们全部完成时收到通知,您有多种选择。一种简单的方法是在发出第一个请求之前初始化CountdownEvent,然后在发出请求后让主线程等待该事件。异步回调方法每个都在完成时发出该事件的信号。这样,您可以确保在主线程继续之前所有请求都已完成。

    【讨论】:

    • 但是 TPL 比 APM更容易。如果我们能两全其美,那就太好了。
    • 使用 Task.Factory.StartAsync 提供了两全其美...无需使用 CountdownEvent 等进行跟踪。
    • 我需要更仔细地查看 TPL。
    【解决方案3】:

    您可以指定ParallelOptions 来提高并发级别。默认值对于 CPU 密集型任务是合理的,但您正在处理 I/O 密集型任务,因此覆盖该行为是有意义的。

    【讨论】:

    • 我认为增加并发级别只能达到允许的最大并发数?即如果你有 8 个内核,你可以将并发级别设置为任何值..但是高于 8 不会做任何事情...
    • @puffpio:它所说的只是:“MaxDegreeOfParallelism 将通过传递此 ParallelOptions 实例的 Parallel 方法调用运行的并发操作数限制为设置值,如果它是正的。如果 MaxDegreeOfParallelism 是 - 1,那么并发运行的操作数没有限制。”
    • 是的,这让我很困惑,因为它说“限制”,这对我来说意味着它不会超过你拥有的核心数量。我这么说是因为 Parallel.Invoke 上的页面说:“请注意,使用 Invoke(),您只需表达要同时运行的操作,运行时会处理所有线程调度细节,包括自动缩放到主机。”
    【解决方案4】:

    我将逐字复制a response that I made to another question,因为它同样适用于此处。


    在 I/O 性能方面,您根本无法击败异步编程模型 (APM)。任何时候你都可以使用它,你应该是。幸运的是,Task Parallel Library (TPL) 自带支持将 APM 工作与通过the FromAsync factory method 的“纯”TPL 任务组合在一起。

    查看 MSDN 上名为 TPL and Traditional .NET Asynchronous Programming 的 .NET SDK 部分,了解有关如何结合这两种编程模型以实现异步必杀技的更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      相关资源
      最近更新 更多