私があなたの立場だったとしたら、いくつかの可能性を調査します。
- このコードを複数のスレッドから実行している場合は、System.Net.ServicePointManager.DefaultConnectionLimit プロパティに衝突している可能性があります。アプリの起動時に 50 ~ 100 に増やしてみてください。これはあなたの問題ではないと思いますが、これを試すのは以下の他のものよりも簡単です. :-)
- 別の可能性は、サーバーを圧倒していることです。これは通常、シングルスレッドのクライアントでは困難ですが、他の複数のクライアントもサーバーにアクセスしている可能性があるため可能です。しかし、問題は常に #25 で発生するため、より多くの変動が見られると予想されるため、これはありそうにありません。
- クライアントとサーバー間のキープアライブ HTTP 接続で問題が発生している可能性があります。これもありそうにない。
- 25 のハード カットオフは、これが、1 つのクライアント IP から 1 つのサーバー (またはプロキシ) への 25 を超える接続が調整される、エンドまたはサーバーのプロキシまたはファイアウォールの制限である可能性があると考えさせます。
私のお金は後者のものにあります。なぜなら、それは常に良いラウンド数のリクエストで壊れ、デバッガーをステップインしても問題が引き起こされないからです。
これらすべてをテストするには、簡単なことから始めます。各 HTTP 呼び出しの前に遅延 (Thread.Sleep) を挿入し、問題が解決するかどうかを確認します。その場合は、問題が再発するまで遅延を減らします。そうでない場合は、問題が解決するまで遅延を大きくしてください (例: 10 秒)。10 秒の遅延で消えない場合、それは本当に謎であり、診断するにはさらに情報が必要です.
遅れて解消される場合は、その理由と、制限が永続的なもの (変更できないサーバーのファイアウォールなど) なのか、変更できるものなのかを突き止める必要があります。詳細情報を取得するには、リクエストの時間を計って (たとえば、各呼び出しの前後に DateTime.Now をチェックして)、パターンが見られるかどうかを確認します。タイミングがすべて一貫しており、突然大きくなる場合は、ネットワーク/ファイアウォール/プロキシのスロットリングを示唆しています。タイミングが徐々に増加する場合は、サーバーが徐々に過負荷になり、リクエスト キューが長くなっていることを示しています。
リクエストのタイミングに加えて、webclient 呼び出しのタイムアウトをより長く設定して、タイムアウトが無限か、デフォルトより少しだけ長いかを判断できるようにします。これを行うには、タイムアウトをサポートしていないため、WebClient クラスの代替が必要になります。MSDN フォーラムのこのスレッドには、合理的な代替コード サンプルがあります。
コードにタイミングを追加する代わりに、Fiddler を使用できます。
- fiddlerをダウンロードして起動します。
- webclient コードの Proxy プロパティを設定して、フィドラー プロキシ (localhost:8888) を指すようにします。
- アプリを実行して、フィドラーを見てください。