如何优化对服务的并行调用?

时间:2017-06-08 20:10:54

标签: c# .net parallel-processing parallel.foreach

当我需要从服务中提取数据时,我遇到了一个挑战。我正在使用以下对Parallel.ForEach的调用:

Parallel.ForEach(idList, id => GetDetails(id));

GetDetails(id)调用大约半秒钟的Web服务,并将生成的详细信息添加到列表中。

static void GetDetails(string id)
{
    var details = WebService.GetDetails(Key, Secret, id);
    AllDetails.Add(id, details);
}

问题是,我知道该服务可以处理更多的呼叫,但我似乎无法弄清楚如何让我的进程增加更多的呼叫,除非我拆分我的列表并打开这个过程多次。换句话说,如果我打开此应用GetDetails.exe 4次并将ID数分成每个,我将运行时间减少到原来的25%。这告诉我可能性存在,但我不确定如何在不多次增加控制台应用程序的情况下实现它。

希望对于更熟悉并行性的人来说这是一个非常简单的问题,但在我的研究中,我还没有运行多个实例来解决它。

1 个答案:

答案 0 :(得分:1)

一些可能性:

  • WebService.GetDetails(...)有可能使用某种机制来确保一次只发生一次网络请求。
  • .NET本身可能会限制连接数量,无论是给定主机还是一般see this question's answers for details about these kinds of problems
  • 如果WebService.GetDetails(...)重复使用某种标识符(例如会话密钥),服务器可能会限制它为该一个会话接受的并发请求数。
  • 通过使用更多并发请求锤击服务器来尝试解决性能问题通常是个坏主意。如果你控制服务器,那么你就会让你自己的服务器做更多的工作而不是它需要的工作。如果没有,您将面临遭受IP禁止或滥用其服务的风险。值得检查您正在访问的服务是否有一些选项可以批量处理您的请求。
  • 正如Scott Chamberlain在评论中提到的,你需要注意并行进程,因为同时从多个线程访问Dictionary<>这样的结构会导致零星的,难以追踪的错误。使用async请求而不是并行线程可能会更好。如果您对await小心,可以同时激活多个请求,同时仍然只使用一个线程。