【问题标题】:C# - HttpWebRequest / GetResponse performanceC# - HttpWebRequest / GetResponse 性能
【发布时间】:2017-12-29 20:58:36
【问题描述】:

我有一个基于 HTTPS 的 API,我需要多次调用它。使用 HttpWebRequest.Create(uri).GetResponse() 需要 50 毫秒到 500 毫秒或更长的时间来执行。为了检查响应时间,我这样实现:

private void Action()
{
    WebRequest request = HttpWebRequest.Create("https://.....");
    using (WebResponse response = request.GetResponse()) { }
}

然后调用它:

private long getTime()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    Action();
    return sw.ElapsedMilliseconds;
}

多个调用的输出:

Time: 746 ms
Time: 51 ms
Time: 50 ms
Time: 50 ms
Time: 51 ms
Time: 49 ms
Time: 2417 ms ???
Time: 52 ms
Time: 52 ms
Time: 51 ms
Time: 50 ms
Time: 201 ms
Time: 234 ms
Time: 204 ms
Time: 51 ms
Time: 50 ms
Time: 50 ms
Time: 52 ms
Time: 280 ms
Time: 264 ms

第一个问题:我想知道是否有任何方法可以加快 GetResponse 的速度以尽可能缩短它的时间?

现在.. 因为我需要用不同的 URL 发出很多不同的请求,为了加快进程我决定使用TPL Dataflow Block(而不是Parallel.Foreach),因为Parallel.Foreach 主要用于CPU bound 工作,而我正在做的是I/O bound(还有响应的处理,所以还有一些 CPU 工作)。当我使用 TPL Dataflow Block 时,处理 250 个 URL 需要 7 秒才能执行,而 Parallel Foreach 需要 15 秒或更长时间,所以我很肯定 TPL Dataflow Block 的使用是正确的方法。我是如何实现的:

//CALL:
var block = new ActionBlock<string>(uri => Action(uri), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 200 });
foreach (var URL in urlArray)
{
    block.Post(URL);
}
block.Complete();
await block.Completion;

//Action(uri):
private void Action(string uri)
{
    WebRequest request = HttpWebRequest.Create(uri);
    using (WebResponse response = request.GetResponse()) { }
}

由于我对 7 秒的执行不满意,我尝试调整 ServicePointManager 以加快速度,到目前为止我尝试过的事情都没有奏效:

ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.SetTcpKeepAlive(false, 0, 0);
ServicePointManager.DefaultConnectionLimit = 1000;

第二个问题:如果无法加速 GetResponse() 以实现更快的执行,有没有办法调整 TPL Dataflow Block 以获得更好的性能?

编辑:我的目标是尽可能快地执行所有调用。

【问题讨论】:

  • 为什么不使用GetResponseAsync
  • @JeroenHeier 我真的很惊讶我是怎么错过的。真的是我一生中最尴尬的时刻之一。我一定是真的累了。请将您的回复作为答案发布。

标签: c# parallel-processing httpwebrequest webresponse servicepointmanager


【解决方案1】:

您可以使用GetResponseAsync 加速您的解决方案。另请参阅this Micorsoft 演练,其中深入解释了两种方法(同步和异步)。

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多