在64位的Windows HttpWebRequest的GetResponse的延迟 [英] HttpWebRequest GetResponse delay on 64bit Windows

查看:173
本文介绍了在64位的Windows HttpWebRequest的GetResponse的延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近尝试在Windows上运行的64位版本的.NET应用程序,惊讶地发现,我所有的 HttpWebRequest.GetResponse()调用Web服务我的本地网络上在谈论巨大(约500毫秒)的时间来完成。下面是关于我的测试设置了几个信息:

I recently tried running a .NET application on 64bit versions of Windows and was surprised to notice that all my HttpWebRequest.GetResponse() calls to web services on my local network were talking huge (around 500ms) time to complete. Here's a few info regarding my test setup:

  • 在.NET 3.5
  • 在Windows Vista家庭premium 32位,Windows Vista商业版64位和Windows Server 2008 64位。

测试code为实施例的一个略加修改的版本中MSDN's文章对 HttpWebRequest.GetResponse 。我执行的唯一的修改只是一个循环,这样我可以时间为10 consequtive电话,并基本身份验证,因为Web服务我是针对需要验证:

The test code is a slightly modified version of the example described in MSDN's article on HttpWebRequest.GetResponse. The only modifications I performed were just a loop so that I could time 10 consequtive calls, and Basic Authentication, since the web service I was targeting needed authentication:

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);
        }
    }
}

我编译针对86的Windows Vista家庭premium和x64的64位Windows计算机程序。这三个机器都在同一个网络交换机与机器托管Web服务连接在一起。下面是我得到的结果:

I compiled the program targeting x86 for Windows Vista Home Premium and x64 for the 64bit Windows machines. The three machines were connected on the same network switch together with the machine hosting the web service. Here are the results I got:

  • Windows Vista家庭premium 32位,x86汇编:以第一个调用的GetResponse()围绕 150ms的完成,而所有的连续通话前后花了 10ms的
  • Windows Vista商业版64位,Server 2008中的64位,x86和x64组件:第一个调用了周围的 1000毫秒,而每个连续的调用完成的 500ms的。如果我停用的HttpWebRequest。preAuthenticate ,每个的GetResponse 结束在 1000毫秒(其中是相当合理的,因为在这种情况下,每个请求触发两个单独的HTTP请求,1结束与未经授权和一个得到适当的反应)。
  • Windows Vista Home Premium 32bit, x86 assembly: The first call to GetResponse() was completed in around 150ms, while all consecutive calls took around 10ms.
  • Windows Vista Business 64bit, Server 2008 64 bit, x86 and x64 assemblies: The first call took around 1000ms, while each consecutive call completed in 500ms. If I disable HttpWebRequest.PreAuthenticate, each GetResponse completes in 1000ms (which is quite reasonable since in this case each request triggers two separate HTTP requests, one ending up with Unauthorized and one the gets the proper response).

是否有人有原因的线索,我得到的64位版本的Windows这样长的的GetResponse 延误?

Does anybody have a clue of the reason I get such long GetResponse delays on the 64 bit versions of Windows?

信息的问题:

  • 我测量的响应时间(通过萤火虫的建议)当执行与Firefox 3.5的要求和请求 - 响应延迟是相同的所有机器,即问题没有重现。
  • 在我做了进一步的分析数据包使用Wireshark,并提出了以下结果:

32位:在TCP会话如下:

32bit: The tcp conversation is as follows:

  • 主机 - >服务器新的Web请求 HTTP GET / HTTP / 1.1
  • 服务器 - >主机两个TCP段(大约为5ms增量)
  • 主机 - >服务器的TCP ACK(确认两个部分)(〜10us的三角形)
  • 服务器 - >主机HTTP / 1.1 200 OK(〜800us增量)
  • 主机 - >服务器新的Web请求 HTTP GET / HTTP / 1.1和放大器;为previous段捎带TCP ACK(HTTP / 1.1 200 OK)(〜10ms的三角形)
  • host->server New web request HTTP GET/HTTP/1.1
  • server->host Two TCP segments (~5ms delta)
  • host->server Tcp Ack (acknowledges both segments) (~10us delta)
  • server->host HTTP/1.1 200 OK (~800us delta)
  • host->server New web request HTTP GET/HTTP/1.1 & piggybacked TCP ack for previous segment (HTTP/1.1 200 OK) (~10ms delta)

64位:在TCP会话如下:

64 bit: The tcp conversation is as follows:

  • 主机 - >服务器新的Web请求 HTTP GET / HTTP / 1.1
  • 服务器 - >主机两个TCP段(〜5ms的三角洲,同32位)
  • 主机 - >服务器的TCP ACK(确认两个部分)(〜10us的三角洲,同32位)
  • 服务器 - >主机HTTP / 1.1 200 OK(〜800us三角洲,同32位)
  • 主机 - >为previous架服务器的TCP ACK(HTTP / 1.1 200 OK)(!!! 96ms)
  • 主机 - >服务器新的Web请求的HTTP GET / HTTP / 1.1(!!! 309ms)
  • host->server New web request HTTP GET/HTTP/1.1
  • server->host Two TCP segments (~5ms delta, same as 32bit)
  • host->server Tcp Ack (acknowledges both segments) (~10us delta, same as 32 bit)
  • server->host HTTP/1.1 200 OK (~800us delta, same as 32 bit)
  • host->server TCP ack for previous frame (HTTP/1.1 200 OK) (!!! 96ms)
  • host->server New web request HTTP GET/HTTP/1.1 (!!! 309ms)

我得到在64位机器的500ms的大多是发生在最后两个步骤。请注意,这绝对是不相关的TCP堆栈(因为一切工作正常与Firefox)。究其原因,我们得到的最后两个步骤不同的TCP确认模式(背负在32位,而在64位独立的TCP确认帧)是新的Web请求被延迟309 + 96ms的64位的情况下(所以TCP堆栈输出一个单独的确认帧,它不能等待应用层)。

The 500ms I get on the 64 bit machines is mostly occured in the last two steps. Note that this is definitely not related to the TCP stack (since everything works ok with firefox). The reason we get different TCP Ack pattern in the last two steps (piggybacked in 32 bit, while separate TCP Ack frame in 64 bit) is that the new Web Request is delayed for 309+96ms in the 64bit case (so the TCP stack outputs a separate Ack frame, it can not wait for the application layer).

所以,它看起来像:

  • 的问题是由在完成web请求和新发行的增量时间而引起的。
  • 的问题有事情做与.NET Framework? (绝对不是TCP相关)。
  • 在该问题发生在从MSDN(MS不能错吧?)采取股票的Microsoft code。

任何线索?

推荐答案

就为了其他任何人遇到这种线程是有问题的。

Just for anyone else that comes across this thread and is having issues.

在64位系统延迟的原因是Web客户端等待Windows来返回代理值。

The cause of the delay on 64bit systems is the WebClient waiting for Windows to return the proxy value.

写您的code这样来解决这个问题。

Write your code like this to overcome this issue.

WebClient wc = New WebClient;
wc.Proxy = null;

这将消除被一些用户延迟(包括我自己:))

That will eliminate the delay seen by some users (including myself :))

很高兴我终于可以回馈到已经帮了我这么多的社区:)

Glad I could finally give something back to the community that has helped me so much :)

这篇关于在64位的Windows HttpWebRequest的GetResponse的延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆