C# - HttpWebRequest/GetResponse 性能
C# - HttpWebRequest / GetResponse performance
我有一个基于 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 数据流块时,处理 250 个 URL 最多需要 7 秒才能执行,而 Parallel Foreach 需要 15 秒或更长时间,所以我肯定 TPL 数据流块的使用是正确的方法。我是如何实施的:
//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()) { }
}
而且由于我对 7s 的执行不满意,我尝试调整 ServicePointManager
以加快速度,到目前为止我已经尝试过并且 NONE 有效:
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.SetTcpKeepAlive(false, 0, 0);
ServicePointManager.DefaultConnectionLimit = 1000;
第二个问题:如果无法加快 GetResponse()
以实现更快的执行速度,是否有任何方法可以调整 TPL Dataflow Block
以获得更好的性能?
编辑:我的目标是尽可能快地执行所有调用。
您可以使用 GetResponseAsync. See also this Microsoft 演练加快您的解决方案,其中对两种方法(同步和异步)进行了深入解释。
我有一个基于 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 数据流块时,处理 250 个 URL 最多需要 7 秒才能执行,而 Parallel Foreach 需要 15 秒或更长时间,所以我肯定 TPL 数据流块的使用是正确的方法。我是如何实施的:
//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()) { }
}
而且由于我对 7s 的执行不满意,我尝试调整 ServicePointManager
以加快速度,到目前为止我已经尝试过并且 NONE 有效:
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.SetTcpKeepAlive(false, 0, 0);
ServicePointManager.DefaultConnectionLimit = 1000;
第二个问题:如果无法加快 GetResponse()
以实现更快的执行速度,是否有任何方法可以调整 TPL Dataflow Block
以获得更好的性能?
编辑:我的目标是尽可能快地执行所有调用。
您可以使用 GetResponseAsync. See also this Microsoft 演练加快您的解决方案,其中对两种方法(同步和异步)进行了深入解释。