Currently I have a section of code that needs to make about 7 web service calls to various providers for data. Each call takes a several seconds to execute, so I would like to run them in parallel to speed things up.
目前,我有一段代码需要向各种提供者调用大约7个web服务来获取数据。每次调用都需要几秒钟的时间来执行,因此我希望并行运行它们,以加快速度。
I have wrapped my 7 calls in a Parallel.Invoke which works great at running a couple things at the same time, but on a 2 core server, it will only execute 2 at a time, one per core. Since all I am doing is waiting around for the web service calls to return I would want it to go fetch all 7 and wait for them to come back.
我把我的7个电话用一个平行线包起来。调用可以同时运行一些东西,但是在一个2核心服务器上,它只会一次执行2个,一个核心。因为我所做的就是等待web服务调用返回,所以我希望它去取回所有7,并等待它们返回。
Is there no way to do this? Or perhaps my approach is wrong? Maybe I need to create asynchronous calls to the web services? But then how to wait for them all to come back before moving on?
难道没有办法这么做吗?或者也许我的方法是错误的?也许我需要创建对web服务的异步调用?但是,在继续前进之前,又该如何等待他们都回来呢?
4 个解决方案
#1
5
but on a 2 core server, it will only execute 2 at a time, one per core
但是在2核服务器上,它一次只执行2个,每个核一个
I would question this - Parallel.Invoke will typically run many more tasks than cores in your system.
我想问这个平行的问题。调用通常会比系统中的核心运行更多的任务。
That being said, if you're using asynchronous method call invocations, I would recommend using Task.Factory.FromAsync(...) to generate your seven distinct tasks.
也就是说,如果您正在使用异步方法调用,我建议使用Task.Factory.FromAsync(…)来生成7个不同的任务。
This provides the flexibility of doing other work while the tasks execute, then calling Task.WaitAll
(or Task.WaitAny
) when you decide to use the results.
这提供了在执行任务时执行其他工作,然后调用任务的灵活性。当你决定使用结果时。
Parallel.Invoke, on the other hand, will always block until all seven complete.
平行的。另一方面,调用将始终阻塞,直到全部7个都完成。
#2
1
There's no real need to use Parallel.Invoke
for this. You can go ahead and issue the multiple asynchronous requests (i.e. HttpWebRequest.BeginGetResponse()
). As for being notified when they all complete, you have several options. A simple way would be to initialize a CountdownEvent before you issue the first request, and then have the main thread wait on that event after it's issued the requests. The asynchronous callback methods each signal that event as they complete. That way, you ensure that all requests have completed before your main thread continues.
没有必要使用并行。调用。您可以继续并发出多个异步请求(例如HttpWebRequest.BeginGetResponse())。当它们全部完成时,您有几个选项。一种简单的方法是在发出第一个请求之前初始化CountdownEvent,然后让主线程在发出请求后等待该事件。异步回调方法在事件完成时对每个事件进行通知。这样,您确保在主线程继续之前完成所有请求。
#3
0
You can specify ParallelOptions
to increase the concurrency level. The default is reasonable for CPU-bound tasks, but you're dealing with I/O-bound ones, so it makes sense to override that behavior.
您可以指定并行选项来增加并发级别。默认情况对于cpu绑定的任务是合理的,但是您正在处理I/ o绑定的任务,所以重写这种行为是有意义的。
#4
0
I'm going to copy a response that I made to another question verbatim because it's equally, if not more, applicable here.
我将逐字复制我对另一个问题的回答,因为它在这里同样适用。
You simply cannot beat the Asynchronous Programming Model (APM) when it comes to I/O performance. Anytime you can use it, you should be. Luckily the Task Parallel Library (TPL) comes with baked in support for combining APM work into the mix with "pure" TPL tasks via the FromAsync factory method.
当涉及到I/O性能时,您无法击败异步编程模型(APM)。任何时候你都应该使用它。幸运的是,任务并行库(TPL)是通过支持将APM工作与“纯”TPL任务(通过FromAsync factory方法)结合在一起的。
Check out this section of the .NET SDK on MSDN entitled TPL and Traditional .NET Asynchronous Programming for more information on how to combine these two programming models to achieve async nirvana.
请查看MSDN上的。net SDK的这一部分,标题为TPL和传统。net异步编程,了解如何结合这两个编程模型来实现异步的更多信息。
#1
5
but on a 2 core server, it will only execute 2 at a time, one per core
但是在2核服务器上,它一次只执行2个,每个核一个
I would question this - Parallel.Invoke will typically run many more tasks than cores in your system.
我想问这个平行的问题。调用通常会比系统中的核心运行更多的任务。
That being said, if you're using asynchronous method call invocations, I would recommend using Task.Factory.FromAsync(...) to generate your seven distinct tasks.
也就是说,如果您正在使用异步方法调用,我建议使用Task.Factory.FromAsync(…)来生成7个不同的任务。
This provides the flexibility of doing other work while the tasks execute, then calling Task.WaitAll
(or Task.WaitAny
) when you decide to use the results.
这提供了在执行任务时执行其他工作,然后调用任务的灵活性。当你决定使用结果时。
Parallel.Invoke, on the other hand, will always block until all seven complete.
平行的。另一方面,调用将始终阻塞,直到全部7个都完成。
#2
1
There's no real need to use Parallel.Invoke
for this. You can go ahead and issue the multiple asynchronous requests (i.e. HttpWebRequest.BeginGetResponse()
). As for being notified when they all complete, you have several options. A simple way would be to initialize a CountdownEvent before you issue the first request, and then have the main thread wait on that event after it's issued the requests. The asynchronous callback methods each signal that event as they complete. That way, you ensure that all requests have completed before your main thread continues.
没有必要使用并行。调用。您可以继续并发出多个异步请求(例如HttpWebRequest.BeginGetResponse())。当它们全部完成时,您有几个选项。一种简单的方法是在发出第一个请求之前初始化CountdownEvent,然后让主线程在发出请求后等待该事件。异步回调方法在事件完成时对每个事件进行通知。这样,您确保在主线程继续之前完成所有请求。
#3
0
You can specify ParallelOptions
to increase the concurrency level. The default is reasonable for CPU-bound tasks, but you're dealing with I/O-bound ones, so it makes sense to override that behavior.
您可以指定并行选项来增加并发级别。默认情况对于cpu绑定的任务是合理的,但是您正在处理I/ o绑定的任务,所以重写这种行为是有意义的。
#4
0
I'm going to copy a response that I made to another question verbatim because it's equally, if not more, applicable here.
我将逐字复制我对另一个问题的回答,因为它在这里同样适用。
You simply cannot beat the Asynchronous Programming Model (APM) when it comes to I/O performance. Anytime you can use it, you should be. Luckily the Task Parallel Library (TPL) comes with baked in support for combining APM work into the mix with "pure" TPL tasks via the FromAsync factory method.
当涉及到I/O性能时,您无法击败异步编程模型(APM)。任何时候你都应该使用它。幸运的是,任务并行库(TPL)是通过支持将APM工作与“纯”TPL任务(通过FromAsync factory方法)结合在一起的。
Check out this section of the .NET SDK on MSDN entitled TPL and Traditional .NET Asynchronous Programming for more information on how to combine these two programming models to achieve async nirvana.
请查看MSDN上的。net SDK的这一部分,标题为TPL和传统。net异步编程,了解如何结合这两个编程模型来实现异步的更多信息。