WebClientの2つの接続制限をプログラムで削除するにはどうすればよいですか


88

これらの「細かい」RFCは、すべてのRFCクライアントから、ホストごとに2つを超える接続を使用しないように注意することを義務付けています...

MicrosoftはこれをWebClientに実装しました。私はそれをオフにすることができることを知っています

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
 <system.net> 
  <connectionManagement> 
   <add address="*" maxconnection="100" /> 
  </connectionManagement> 
 </system.net> 
</configuration> 

http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007にあります

しかし、どうすればプログラムでそれを行うことができますか?

Accordin http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx

"DefaultConnectionLimitプロパティを変更しても、既存のServicePointオブジェクトには影響がありません。変更後に初期化されるServicePointオブジェクトにのみ影響します。このプロパティの値が直接または構成を通じて設定されていない場合、値はデフォルトの定数DefaultPersistentConnectionLimitになります。"

WebClientをインスタンス化するときに制限を構成することをお勧めしますが、プログラムの開始時にこの悲しい制限をプログラムで削除するだけでも問題ありません。

私がアクセスするサーバーは、インターネットの通常のWebサーバーではなく、私の制御下にあり、ローカルLANにあります。API呼び出しを実行したいのですが、Webサービスやリモート処理を使用していません


15
それは本当に標準ではありません。RFCでは、クライアントを2つの接続に制限することを「推奨」していますが、これは実際には要件ではありません。おそらく、ポスターは一度に2つ以上のアイテムをダウンロードする必要があります。
Erik Funkenbusch 2009年

12
自分のサーバーのAPIにアクセスします。インターネットのホストに害を与えたくありません。
クリスチャン

12
負荷テストツールを構築するために接続制限を増やしました。2つのmeasley接続でテストをロードするのは本当に難しいです。多くの接続を使用する多くの非ブラウジング理由があると確信しています。
ScottS、2009年

1
ところで、上記の設定は、webclientだけでなく、すべての.Net制御の接続に影響します。
ScottS、2009年

2
なぜ2つ以上ですか?質問を振り返ってみましょう:なぜ非同期で同時に3つ以上のリクエストをサーバーに発行できないのですか?2は文字通り制限です。
Csaba Toth 2013

回答:


50

ここや他の場所からのいくつかのヒントを使用して、私が使用していたWebClientクラスをオーバーライドすることで、アプリケーションでこれを修正することができました。

class AwesomeWebClient : WebClient {
    protected override WebRequest GetWebRequest(Uri address) {
        HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
        req.ServicePoint.ConnectionLimit = 10;
        return (WebRequest)req;
    }
}

28
私見では設定がいることをSystem.Net.ServicePointManager.DefaultConnectionLimit、より良い解決策がある、などと仮定することができないWebRequestHttpWebRequest、例えば、それができますFileRequest
Dennis

120

興味のある人のために:

System.Net.ServicePointManager.DefaultConnectionLimit = x (xは希望する接続数です)

追加の参照は必要ありません

上記の投稿で説明したようにサービスポイントが作成される前に、これが呼び出されていることを確認してください。


これをグローバルのapplication_startに追加できますか?だからそれは作られたすべての接続に影響しますか?
TheAlbear

System.Net.ServicePointManager.DefaultConnectionLimit = xを追加する方法と場所
Arul Sidthan

奇妙なことに、(F12を使用して移動する)DefaultConnectionLimitのコードコメントには、デフォルトがInt32.MaxValueであると記載されています。ただし、デバッグ検査では、主張どおり2です。
crokusek 2017

7

このソリューションでは、接続制限をいつでも変更できます。

private static void ConfigureServicePoint(Uri uri)
{
    var servicePoint = ServicePointManager.FindServicePoint(uri);

    // Increase the number of TCP connections from the default (2)
    servicePoint.ConnectionLimit = 40;
}

初めて誰かがこのFindServicePointを呼び出すと、ServicePointインスタンスが作成され、ServicePointManager内でそれを保持するためのWeakReferenceが作成されます。同じUriに対する後続のマネージャーへのリクエストは、同じインスタンスを返します。接続が後で使用されない場合、GCはそれをクリーンアップします。


1
FindServicePointの唯一の問題は、1つのServicePointが返されることですが、クライアントが取得するServicePointと同じかどうかがわかりません。
jeffa00

2
それは「問題」ではなく、仕事の通常の部分にすぎません。すべてのソリューションと同様に、それをテストする方法を見つける必要があります。私の方法は、.configの設定を "1"に設定し、ひどいパフォーマンスを観察し、コードで(ここに示すように)設定して、パフォーマンスの向上を観察することでした。
そろばん2016

1
これServicePointは(設定と共に)失われますMaxIdleTime
Colin Breame

5

WebClientによって使用されているServicePointオブジェクトを見つけた場合、その接続制限を変更できます。HttpWebRequestオブジェクトには、使用するために構築されたものを取得するためのアクセサーがあるので、そのようにすることができます。運が良ければ、すべてのリクエストが同じServicePointを共有する可能性があるため、一度だけ実行する必要があります。

制限を変更するグローバルな方法を知りません。実行の早い段階でDefaultConnectionLimitを変更した場合は、おそらく問題ありません。

代わりに、ほとんどのサーバーソフトウェアがとにかくスロットルするため、接続制限をそのまま使用することもできます。:)


このサーバーは完全に私の制御下にあるため、私を抑制しません(実際には抑制しますが、別の方法で)
Christian

1
サーバーは多くの接続でスロットルする可能性がありますが、小規模なサーバー(制限されたVMでホストされている)でもこれを経験していません。一方、クライアント側の制限2は、私を後退させました。制限を増やすことで状況は解放されました。
Csaba Toth 2013

1
私も疑問今日のブラウザのいずれかが2のHTTP 1.1 RFCの制限に従うだろうと
チャバ・トス

4

上記のApp.Configの構成に関する状況があります。

これをCONSOLEアプリケーションで有効にするために、System.Configuration参照DLLを追加しました。参照なしでは、上記は役に立たなかった。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.