65

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

然而,挑战在于,我必须进行大量此类查找(数千次),并且我想限制所需的时间。因此我想并行运行请求(比如 10-20)。我使用 ThreadPool 来执行此操作,我的代码的简短版本如下所示:

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>startAsyncLookupreturnLookupResult

最初我认为这可能是第三方的系统很差,但我通过尝试同时从两台不同的机器上运行相同的代码来排除这种情况。这两个中的每一个都需要一个单独的时间,所以我可以排除那个。

然后一位同事告诉我,这可能是 Windows 中的一个限制。我用谷歌搜索了一下,发现在这篇文章中,默认情况下,Windows 将对同一 Web 服务器的并发请求数限制为 HTTP 1.0 的 4 个和 HTTP 1.1 的 2 个(对于 HTTP 1.1,这实际上是根据规范( RFC2068))。

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

所以,我尝试了这个(都坐到 20 点),重新启动了我的计算机,并尝试再次运行我的程序。可悲的是,它似乎没有任何帮助。在运行批处理查找时,我还密切关注资源监视器,我注意到我的应用程序(标题被涂黑的应用程序)仍然只使用两个 TCP 连接。

所以,问题是,为什么这不起作用?我链接到的帖子是否使用了错误的注册表值?这可能不再可能在 Windows 中“破解”(我在 Windows 7 上)吗?

万一有人想知道,我还尝试了 ThreadPool 上 MaxThreads 的不同设置(从 10 到 100),这似乎根本不会影响我的吞吐量,所以问题也不应该存在。

4

4 回答 4

96

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

于 2010-06-02T17:45:26.220 回答
29

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

   System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4
于 2012-10-23T06:29:01.673 回答
2

从您的主要方法中触发并忘记此方法。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);
}
于 2015-02-24T11:07:32.203 回答
0

对于 Internet Explorer 8:运行注册表编辑器并导航到以下键 HKEY_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 或所需的任何数字。

于 2010-06-02T17:41:09.217 回答