我最近尝试在64位版本的Windows上运行.NET应用程序,并且惊讶地发现我对本地网络上的Web服务的所有HttpWebRequest.GetResponse()
调用都说话时间很长(大约500毫秒)。以下是有关我的测试设置的一些信息:
测试代码是MSDN's article on HttpWebRequest.GetResponse
中描述的示例的略微修改版本。我执行的唯一修改只是一个循环,因此我可以计算10个连续调用和基本身份验证,因为我定位的Web服务需要身份验证:
using System;
using System.Diagnostics;
using System.Net;
using System.Text;
using System.IO;
public class Program
{
// Specify the URL to receive the request.
public static void Main (string[] args)
{
CredentialCache crCache = null;
Stopwatch s = new Stopwatch();
for (int i = 0; i < 10; i++)
{
s.Reset();
s.Start();
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create (args[0]);
// Set some reasonable limits on resources used by this request
request.MaximumAutomaticRedirections = 4;
request.MaximumResponseHeadersLength = 4;
// Set credentials to use for this request.
if (crCache == null)
{
crCache = new CredentialCache();
crCache.Add(new Uri(args[0]), "Basic",
new NetworkCredential("user", "password"));
}
request.Credentials = crCache;
request.PreAuthenticate = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine("Content length is {0}", response.ContentLength);
Console.WriteLine("Content type is {0}", response.ContentType);
// Get the stream associated with the response.
Stream receiveStream = response.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
Console.WriteLine("Response stream received.");
//Console.WriteLine (readStream.ReadToEnd ());
response.Close();
readStream.Close();
s.Stop();
Console.WriteLine("Request took: " + s.ElapsedMilliseconds);
}
}
}
我编译了针对Windows Vista Home Premium的x86和针对64位Windows计算机的x64的程序。这三台机器与托管Web服务的机器一起连接在同一网络交换机上。以下是我得到的结果:
GetResponse()
的电话已在 150ms 内完成,而所有连续电话都在 10ms的即可。HttpWebRequest.PreAuthenticate
,则每个GetResponse
都会在 1000毫秒中完成(这是非常合理的,因为在这种情况下,每个请求都会触发两个单独的HTTP请求,一个以未授权的方式结束,另一个以得到正确的回应。)。有没有人知道我在64位版本的Windows上出现如此长的GetResponse
延迟的原因?
问题的其他信息:
32位:tcp对话如下:
64位:tcp会话如下:
我在64位计算机上获得的500毫秒大部分都是在最后两个步骤中出现的。请注意,这绝对与TCP堆栈无关(因为一切都可以使用firefox)。我们在最后两个步骤中获得不同的TCP Ack模式(在32位中捎带,而64位中的单独TCP Ack帧)的原因是新的Web请求在64位情况下延迟了309 + 96ms(因此TCP堆栈输出一个单独的Ack框架,它不能等待应用层。)
所以,似乎:
任何线索?
答案 0 :(得分:16)
只是遇到遇到这个问题并遇到问题的其他人。
64位系统延迟的原因是WebClient等待Windows返回代理值。
编写这样的代码来克服这个问题。
WebClient wc = New WebClient;
wc.Proxy = null;
这将消除一些用户(包括我自己)所看到的延迟。)
很高兴我终于可以回馈给那些帮助过我的社区了。)
答案 1 :(得分:4)
我遇到了同样的问题,因为我有2个webapps在同一台服务器上调用api webapp,所以它让我抓狂。我一直有500毫秒的响应时间。如果我使用WebRequest对象多次调用我的api,则每个调用大约需要500ms。
这是我针对我的特殊情况的解决方案。我的Windows Server 2008 RC2 64位盒子已运行Nod32。它具有称为“Web访问保护”的功能。关闭http / https扫描仪。然后我的响应时间从一致的500毫秒变为30-60毫秒。
答案 2 :(得分:1)
你能确定吗
<system.net><settings><servicePointManager useNagleAlgorithm="false"/>
然后再试一次?
如果仍然失败,是否有内容长度标题?两种情况下的价值相同吗?最后,但并非最不重要的是,响应中是否有额外的字节?哦,你应该启用这条线:
//Console.WriteLine (readStream.ReadToEnd ());
只是为了确保重复使用连接(没有它可能会发生,但以防万一)。
答案 3 :(得分:1)
我的解决方案是:
ServicePointManager.UseNagleAlgorithm = false
请注意,您必须在之前设置此,以创建HttpWebRequest对象。如果我事后再设置它,那么它对我不起作用。
速度提升 huge 因为我们创建了大量小型JSON请求。可能快10倍。
答案 4 :(得分:0)
此以下MS KB可能对此情况有用。 http://support.microsoft.com/kb/823764
[更新9/2/10]
在上面的评论中,您应该在同一台机器上进行此测试。正如我所提到的,我将在64it机器上运行32位可执行文件,看看我得到了什么测量值。
64位计算机上的应用程序速度慢得多,这可能与机器配置本身有关 - 可能是网卡有问题,网络驱动程序不良,网络问题等?
所以,首先我要在同一台64位机器上运行的32位和64位应用程序之间进行苹果对比。这将显示问题是由于机器配置还是其他原因。
答案 5 :(得分:0)
尝试将keep alive设置为false(request.KeepAlive = false;
)
答案 6 :(得分:0)
正如James Ponting所说,
64位系统延迟的原因是WebClient正在等待 Windows返回代理值。
解决方案:
req = HttpWebRequest.Create(url) as HttpWebRequest;
req.Proxy = null;
res = req.GetResponse() as HttpWebResponse;
答案 7 :(得分:-3)
HttpWebRequest
和HttpWebResponse
都实现了IDisposable
,但我没有看到你处理这些对象。我确实看到你关闭了响应和响应流,但根据我的经验,如果你不处理所有这些对象,你可能会得到很长的延迟,否则看起来是随机的。