web-dev-qa-db-ja.com

System.Net.WebClientが不当に遅い

System.Net.WebClient.DownloadData() メソッドを使用すると、応答時間が非常に遅くなります。

.NETのWebClientクラスを使用してURLをフェッチする場合、応答を取得するまでに約10秒かかりますが、同じページがブラウザによって1秒未満でフェッチされます。そして、これは0.5kB以下のサイズのデータ​​でです。

問題が発生する可能性がある場合、リクエストにはPOST/GETパラメータとユーザーエージェントヘッダーが含まれます。

.NETでデータをダウンロードする他の方法で同じ問題が発生するかどうかは(まだ)試していませんが、同様の結果が得られるのではないかと疑っています。 (.NETでのWebリクエストは非常に遅いと感じていました...)

これの原因は何でしょうか?

編集:
私はSystem.Net.HttpWebRequest代わりに、次のメソッドを使用すると、すべてのリクエストが1秒未満で終了します。

public static string DownloadText(string url)
        var request = (HttpWebRequest)WebRequest.Create(url);
        var response = (HttpWebResponse)request.GetResponse();

        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            return reader.ReadToEnd();
        }
}


この(古い)メソッドを使用しながらSystem.Net.WebClientリクエストが完了するまで15〜30秒かかります:

public static string DownloadText(string url)
{
       var client = new WebClient();
       byte[] data = client.DownloadData(url);
       return client.Encoding.GetString(data);
}
41
moevi

WebRequestでその問題がありました。 Proxy = nullを設定してみてください。

    WebClient wc = new WebClient();
    wc.Proxy = null;

デフォルトでは、WebClient、WebRequestは使用するプロキシをIE設定から決定します。実際のリクエストが送信されるまでに5秒程度の遅延が発生することがあります。

これは、HTTPバインディングを使用するWCFサービスを含む、WebRequestを使用するすべてのクラスに適用されます。通常、この静的コードはアプリケーションの起動時に使用できます。

WebRequest.DefaultWebProxy = null;
81
Alex Burtsev

ここからWiresharkをダウンロード http://www.wireshark.org/

ネットワークパケットをキャプチャし、「http」パケットをフィルタリングします。すぐに答えが得られるはずです。

2
Harvey Kwok

設定WebRequest.DefaultWebProxy = null;またはclient.Proxy = nullは何もしませんでした。iOSでXamarinを使用しています

これを修正するために2つのことを行いました。

WebRequestとSystem.Netを使用しないdownloadString関数を作成しました。

        public static async Task<string> FnDownloadStringWithoutWebRequest(string url)
        {
            using (var client = new HttpClient())
            {
                //Define Headers
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                var response = await client.GetAsync(url);

                if (response.IsSuccessStatusCode)
                {
                    string responseContent = await response.Content.ReadAsStringAsync();
                    //dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject(responseContent);
                    return responseContent;
                }
                Logger.DefaultLogger.LogError(LogLevel.NORMAL, "GoogleLoginManager.FnDownloadString", "error fetching string, code: " + response.StatusCode);
                return "";
            }
        }

ただし、Managed HttpClientを使用すると、これはまだ遅くなります。

つまり、2番目に、Visual Studio Community for Macで、ソリューション->オプション->でプロジェクトを右クリックします。 HttpClient実装をManagedではなくNSUrlSessionに設定します。

スクリーンショット:HttpClient実装をManagedではなくNSUrlSessionに設定

ManagedはiOSに完全に統合されておらず、TLS 1.2をサポートしていないため、iOS9 +でデフォルトとして設定されているATS標準をサポートしていません。以下を参照してください:

https://docs.Microsoft.com/en-us/xamarin/ios/app-fundamentals/ats

これらの両方の変更により、文字列のダウンロードは常に非常に高速です(<< 1秒)。これらの両方の変更がない場合、2回または3回の試行ごとに、downloadStringに1分以上かかりました。


参考までに、もう1つ試すことができますが、もう必要ありません:

            //var authgoogle = new OAuth2Authenticator(...);
            //authgoogle.Completed...

            if (authgoogle.IsUsingNativeUI)
            {
                // Step 2.1 Creating Login UI 
                // In order to access SFSafariViewController API the cast is neccessary
                SafariServices.SFSafariViewController c = null;
                c = (SafariServices.SFSafariViewController)ui_object;
                PresentViewController(c, true, null);
            }
            else
            {
                PresentViewController(ui_object, true, null);
            }

私の経験では、おそらくSafariControllerは必要ありません。

1
sschmidTU

Wiresharkのもう1つの代替手段(これも無料)は Microsoft Network Monitor です。

0
Uwe Keim

IE設定([接続]タブ-LAN設定)で自動プロキシ設定をオンにすると、一部のワークステーションでWebClientが遅くなる場合があります。

0
Richard

テストに使用しているブラウザは何ですか?

デフォルトを使用してみてくださいIEインストール。System.Net.WebClientはローカルIE設定、プロキシなどを使用します。

0
TFD

WebClientのダウンロードが非常に遅いもう1つの原因は、ダウンロード先のメディアです。 USBキーのような遅いデバイスの場合、ダウンロード速度に大きな影響を与える可能性があります。別のドライブからこのUSBに5MB /秒でファイルをコピーできたとしても、HDDに6MB /秒、USBキーに700kb /秒でダウンロードできました。 wgetは同じ動作を示します。これもここで報告されます:

https://superuser.com/questions/413750/why-is-downloading-over-usb-so-slow

したがって、これがシナリオである場合、代替ソリューションは、最初にHDDにダウンロードし、ダウンロードの完了後に低速のメディアにファイルをコピーすることです。

0
Mr. Bungle

.NET Webリクエストについて本質的に遅いものはありません。そのコードは問題ないはずです。私は定期的にWebClientを使用しており、非常に高速に動作します。

各方向のペイロードの大きさはどれくらいですか?ばかげた質問かもしれませんが、それは単に帯域幅の制限ですか?

IMOで最も可能性が高いのは、Webサイトがスピンダウンしていて、URLにアクセスしたときにWebサイトの応答が遅いことです。これは、クライアントの責任ではありません。何らかの理由でDNSが遅い(その場合、IPを「ホスト」ファイルにハードコードできる)か、途中のプロキシサーバーが遅い可能性もあります。

Webサイトがあなたのものではない場合、それらが異常な使用を検出しており、意図的にスクレイパーに迷惑をかけるために遅延を挿入している可能性もあります。

私はFiddler(無料のシンプルなWebインスペクター)を入手して、タイミングを調べます。

0
Marc Gravell