web-dev-qa-db-ja.com

複数のHTTPリクエストを並行して実行しようとしていますが、Windows(レジストリ)によって制限されています

単純なHTTPリクエストを介してサードパーティからルックアップ機能にアクセスするアプリケーション(winforms C#.NET 4.0)を開発しています。パラメーターを指定して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>)を埋め、startAsyncLookupを呼び出し、コールバック関数returnLookupResultを提供して各結果を返します。これは機能しますが、必要なスループットが得られないことがわかりました。

最初は、サードパーティのシステムが貧弱であるかもしれないと思っていましたが、同時に2つの異なるマシンから同じコードを実行しようとして、これを除外しました。 2つはそれぞれ1つだけでしたので、その1つを除外できました。

それから同僚は、これがWindowsの制限かもしれないと私に教えてくれました。私は少しグーグルで見つけましたが、他の人の間で この投稿 デフォルトでは、Windowsは同じWebサーバーへの同時リクエストの数をHTTP 1.0では4に、HTTP 1.1では2に制限しています(HTTP 1.1の場合はこれ実際には仕様(RFC2068)に準拠しています)。

上記の同じ投稿も、これらの制限を増やす方法を提供しました。 2つのレジストリ値を[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings](MaxConnectionsPerServerおよびMaxConnectionsPer1_0Server)に追加することにより、自分でこれを制御できます。

そこで、私はこれを試して(両方とも20まで)、コンピューターを再起動し、プログラムを再度実行しようとしました。残念ながら、それは何の助けにもならないようでした。また、バッチルックアップの実行中にリソースモニター( スクリーンショットを参照 )に注目しましたが、アプリケーション(タイトルが黒で表示されているもの)がまだ2つしか使用していないことに気付きましたTCP接続。

質問は、なぜこれが機能しないのかということです。間違ったレジストリ値を使用してリンクしている投稿はありますか?これはおそらくWindowsで「ハッキング」することはおそらく不可能でしょうか(Windows 7を使用しています)。

どんなアイデアでも大歓迎です:)

念のため、誰かがThreadPoolのMaxThreadsの設定を変えてみました(10から100まで)が、これはスループットにまったく影響を与えないようでしたので、問題はないはずです。

62
Julian

ServicePoint の問題です。 HTTP接続の接続管理を提供します。 ServicePointオブジェクトで許可される同時接続のデフォルトの最大数は2です。したがって、それを増やす必要がある場合は、 ServicePointManager.DefaultConnectionLimit プロパティを使用できます。 MSDNのリンクをチェックすると、サンプルが表示されます。そして、必要な値を設定します。

95
Incognito

誰かのためのより速い参照のため。ホストごとの接続制限を増やすには、Main()で、またはHTTP要求の作成を開始する前であればいつでもこれを行うことができます。

   System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4
28
Matt

このメソッドをメインメソッドから起動して忘れてください。 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);
}

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または任意の数値に設定します。

0
Gary