Ear*_*rlz 71 c# performance http httpwebrequest
我正在使用开源库连接到我的网络服务器.我担心网络服务器的速度非常慢,然后我尝试用Ruby做一个简单的测试,我得到了这些结果
Ruby程序:10个HTTP GET的2.11秒
Ruby程序:100个HTTP GET的18.13秒
C#库:10个HTTP GET的20.81秒
C#库:100个HTTP GET的36847.46seconds
我已经分析并发现问题是这个功能:
private HttpWebResponse GetRawResponse(HttpWebRequest request) {
HttpWebResponse raw = null;
try {
raw = (HttpWebResponse)request.GetResponse(); //This line!
}
catch (WebException ex) {
if (ex.Response is HttpWebResponse) {
raw = ex.Response as HttpWebResponse;
}
}
return raw;
}
Run Code Online (Sandbox Code Playgroud)
标记的行自己完成需要1秒以上,而执行1请求的ruby程序需要0.3秒.我也在127.0.0.1上进行所有这些测试,因此网络带宽不是问题.
什么可能导致这个巨大的减速?
UPDATE
查看更改的基准测试结果.我实际测试了10 GET而不是100,我更新了结果.
Jam*_*and 169
我发现有慢速Web请求的主要罪魁祸首是代理属性.如果在调用GetResponse方法之前将此属性设置为null,则查询将跳过代理自动检测步骤:
request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse())
{
}
Run Code Online (Sandbox Code Playgroud)
在返回响应之前,代理自动检测最多需要7秒才能进行查询.默认情况下,为HttpWebRequest对象设置此属性有点烦人.
Man*_*anu 20
这可能与您一次打开多个连接的事实有关.默认情况下,最大打开HTTP连接数设置为2.尝试将此添加到您的.config文件,看看它是否有帮助:
<system.net>
.......
<connectionManagement>
<add address="*" maxconnection="20"/>
</connectionManagement>
</system.net>
Run Code Online (Sandbox Code Playgroud)
小智 10
我在VB.Net MVC项目中遇到了类似的问题.
在我的电脑上本地(Windows 7),它花了不到1秒的时间来点击页面请求,但在服务器(Windows Server 2008 R2)上,每个页面请求花了20多秒.
我尝试了将代理设置为null的组合
System.Net.WebRequest.DefaultWebProxy = Nothing
request.Proxy = System.Net.WebRequest.DefaultWebProxy
Run Code Online (Sandbox Code Playgroud)
并通过添加更改配置文件
<system.net>
.......
<connectionManagement>
<add address="*" maxconnection="20"/>
</connectionManagement>
</system.net>
Run Code Online (Sandbox Code Playgroud)
这仍然没有减少服务器上的慢页面请求时间.最后,解决方案是取消选中服务器本身IE选项中的"自动检测设置"选项.(在"工具" - >"Internet选项"下,选择"连接"选项卡.按"局域网设置"按钮)
在我取消选中服务器上的此浏览器选项后,所有页面请求时间立即从20秒降至1秒以下.
我开始在这个区域观察到类似于OP的减速,当增加MaxConnections时会有所改善.
ServicePointManager.DefaultConnectionLimit = 4;
Run Code Online (Sandbox Code Playgroud)
但是在构建了这么多WebRequest之后,延迟又回来了.
在我的情况下,问题在于我正在调用POST并且没有对响应感到困扰,因此没有采取或做任何事情.不幸的是,这让WebRequest浮出水面,直到它们超时.
修复是拿起响应然后关闭它.
WebRequest webRequest = WebRequest.Create(sURL);
webRequest.Method = "POST";
webRequest.ContentLength = byteDataGZ.Length;
webRequest.Proxy = null;
using (var requestStream = webRequest.GetRequestStream())
{
requestStream.WriteTimeout = 500;
requestStream.Write(byteDataGZ, 0, byteDataGZ.Length);
requestStream.Close();
}
// Get the response so that we don't leave this request hanging around
WebResponse response = webRequest.GetResponse();
response.Close();
Run Code Online (Sandbox Code Playgroud)