代码之家  ›  专栏  ›  技术社区  ›  Julian

试图并行运行多个HTTP请求,但受Windows(注册表)限制

  •  62
  • Julian  · 技术社区  · 16 年前

    我正在开发一个应用程序(winforms c.net 4.0),通过一个简单的HTTP请求从第三方访问查找功能。我用一个参数调用一个URL,作为回报,我得到一个带有查找结果的小字符串。足够简单。

    然而,我面临的挑战是,我必须进行大量的查找(几千次),我想限制所需的时间。因此,我希望并行运行请求(比如10-20)。我使用一个线程工具来执行此操作,我的代码的简短版本如下所示:

    public void startAsyncLookup(Action<LookupResult> returnLookupResult)
    {
        this.returnLookupResult = returnLookupResult;
    
        foreach (string number in numbersToLookup)
        {
            ThreadPool.QueueUserWorkItem(lookupNumber, number);
        }
    }
    
    public void lookupNumber(Object threadContext)
    {
        string numberToLookup = (string)threadContext;
        string url = @"http://some.url.com/?number=" + numberToLookup;
        WebClient webClient = new WebClient();
        Stream responseData = webClient.OpenRead(url);
        LookupResult lookupResult = parseLookupResult(responseData);
    
        returnLookupResult(lookupResult);
    }
    

    我填满 numbersToLookup (A) List<String> )从另一个地方打电话 startAsyncLookup 并提供回调功能 returnLookupResult 返回每个结果。这是可行的,但我发现我没有得到我想要的吞吐量。

    起初我认为这可能是第三方的系统不好,但我试图同时从两台不同的机器上运行相同的代码来排除这一点。每两个都花了一个人的时间,所以我可以排除这一个。

    然后一位同事告诉我,这可能是Windows的一个限制。我在网上搜索了一下,在其他人中找到了 this post 默认情况下,Windows将对同一Web服务器的同时请求数限制为4(对于HTTP 1.0)和2(对于HTTP 1.1,这实际上是根据规范(RFC2068))。

    上面提到的同一篇文章也提供了一种增加这些限制的方法。通过将两个注册表值添加到 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings] (MaxConnectionsPerServer和MaxConnectionsPer1-0Server),我可以自己控制。

    所以,我尝试了这个(两次都是20次),重新启动了我的电脑,并试图再次运行我的程序。可悲的是,它似乎没有任何帮助。我还监视了资源监视器( see screen shot )在运行批量查找时,我注意到我的应用程序(标题为blacked out的应用程序)仍然只使用两个TCP连接。

    所以,问题是,为什么这个不起作用?我链接到的文章是否使用了错误的注册表值?这是否可能再也不能在Windows中“黑客”了(我在Windows7上)?

    任何想法都将受到高度赞赏:)

    为了以防万一,我还尝试了在threadpool上为maxthreads设置不同的设置(从10到100),这似乎根本不会影响我的吞吐量,所以问题也不应该存在。

    4 回复  |  直到 11 年前
        1
  •  95
  •   Incognito    16 年前

    这是问题 ServicePoint . 它为HTTP连接提供连接管理。 ServicePoint对象允许的默认最大并发连接数为2。 所以如果你需要增加它,你可以使用 ServicePointManager.DefaultConnectionLimit 财产。只要查看msdn中的链接,就可以看到一个示例。并设置所需的值。

        2
  •  28
  •   Matt    13 年前

    为某人提供更快的参考。要增加每个主机的连接限制,可以在main()中或开始发出HTTP请求之前的任何时间执行此操作。

       System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4
    
        3
  •  2
  •   John Odom    11 年前

    从主方法中激发并忽略此方法。icognito用户正确,同一时间只能播放2个线程。

    private static void openServicePoint()
    {
        ServicePointManager.UseNagleAlgorithm = true;
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.CheckCertificateRevocationList = true;
        ServicePointManager.DefaultConnectionLimit = 10000;
        Uri MS = new Uri("http://My awesome web site");
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(MS);
    }
    
        4
  •  0
  •   Gary    16 年前

    对于Internet Explorer 8: 运行注册表编辑器并导航到以下项:HKEY\U local\machine\software\microsoft\Internet Explorer\main\featurecontrol\feature\maxconnection sperserver

    和

    hkey_local_machine\software\microsoft\internet explorer\main\featurecontrol\feature_maxconnection sper1_0server

    如果缺少Feature_MaxConnectionsPerServer和Feature_MaxConnectionsPer1_0Server,则创建它们。现在为两个子键(上面列出)创建名为iexplore.exe的dword值,并将其值设置为10或任何所需的数字。