C#-HttpWebRequest/GetResponse性能
我有一个基于HTTPS的API,我需要多次调用它。使用HttpWebRequest.Create(uri).GetResponse()需要50毫秒到500毫秒或更长时间才能执行。为了检查响应时间,我执行了如下操作:C#-HttpWebRequest/GetResponse性能,c#,parallel-processing,httpwebrequest,webresponse,servicepointmanager,C#,Parallel Processing,Httpwebrequest,Webresponse,Servicepointmanager,我有一个基于HTTPS的API,我需要多次调用它。使用HttpWebRequest.Create(uri).GetResponse()需要50毫秒到500毫秒或更长时间才能执行。为了检查响应时间,我执行了如下操作: private void Action() { WebRequest request = HttpWebRequest.Create("https://....."); using (WebResponse response = request.GetResponse
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数据流块(而不是Parallel.Foreach
),因为Parallel.Foreach
主要用于CPU绑定的I/O绑定的(还有响应的处理,所以也需要一些CPU工作)。当我使用TPL数据流块时,250个URL的处理需要7秒才能执行,而并行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()) { }
}
第二个问题:如果无法加速GetResponse()
以实现更快的执行,有没有办法调整TPL数据流块
以获得更好的性能?
编辑:我的目标是尽可能快地执行所有调用。您可以通过使用来加快解决方案的速度。另请参阅Micorsoft演练,其中介绍了两种方法(同步和异步)深入解释。为什么不使用?@JeroenHeier我真的很惊讶我错过了这个。这真是我一生中最尴尬的时刻之一。我一定很累了。请将你的回复作为回答。
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
ServicePointManager.SetTcpKeepAlive(false, 0, 0);
ServicePointManager.DefaultConnectionLimit = 1000;