我在IIS中有REST Web API服务,它接收一组请求对象。用户可以输入100个以上的请求对象。
我想同时运行这个100请求,然后汇总结果并将其发回。这涉及I / O操作(调用每个请求的后端服务)和CPU绑定操作(计算几个响应元素)
代码段 -
using System.Threading.Tasks;
....
var taskArray = new Task<FlightInformation>[multiFlightStatusRequest.FlightRequests.Count];
for (int i = 0; i < multiFlightStatusRequest.FlightRequests.Count; i++)
{
var z = i;
taskArray[z] = Tasks.Task.Run(() =>
PerformLogic(multiFlightStatusRequest.FlightRequests[z],lite, fetchRouteByAnyLeg)
);
}
Task.WaitAll(taskArray);
for (int i = 0; i < taskArray.Length; i++)
{
flightInformations.Add(taskArray[i].Result);
}
public Object PerformLogic(Request,...)
{
//multiple IO operations each depends on the outcome of the previous result
//Computations after getting the result from all I/O operations
}
如果我单独运行PerformLogic操作(对于1个对象),它需要300毫秒,现在我的要求是当我在单个请求中为100个对象运行此PerformLogic()时,它应该花费大约2秒。
PerformLogic()具有以下步骤:1。调用第三方Web服务以获取一些详细信息2.根据详细信息调用另一个第三方Web服务3.从Web服务收集结果,应用少量转换
但是使用Task.run()需要大约7秒,我想知道处理并发性的最佳方法,并达到2秒的理想NFR。 我可以看到,在任何时候,7-8个线程同时工作
不确定我是否可以产生100个线程或任务可能会让我们看到更好的性能。请建议一种有效处理此问题的方法。
答案 0 :(得分:3)
从此判断
public Object PerformLogic(Request,...)
{
//multiple IO operations each depends on the outcome of the previous result
//Computations after getting the result from all I/O operations
}
我打赌PerformLogic
花费大部分时间等待IO操作。如果是这样,async
就有了希望。您将不得不重写PerformLogic
甚至IO操作 - async
需要在所有级别(从顶部到底部)中出现。但如果你可以做到,结果应该快得多。
除此之外 - 获得更快的硬件。如果8个核心需要7秒,那么获得32个核心。它价格昂贵,但仍然比重写代码便宜。
答案 1 :(得分:1)
首先,不要重新发明轮子。 PLINQ完全能够并行完成工作,不需要手动任务处理或结果合并。
如果你想要在2秒内完成100个任务完成100个任务,你需要至少15个并行工作者,忽略并行化本身的成本。
var results = multiFlightStatusRequest.FlightRequests
.AsParallel()
.WithDegreeOfParallelism(15)
.Select(flightRequest => PerformLogic(flightRequest, lite, fetchRouteByAnyLeg)
.ToList();
现在您告诉PLinq使用15个并发工作程序来处理您的任务队列。你确定你的机器能胜任这项任务吗?你可以把你想要的任何数字放在那里,这并不意味着你的计算机神奇地获得了这样做的能力。
另一个选择是查看您的PerformLogic
方法并对其进行优化。你称之为100次,也许值得优化。