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);
}
WebRequestでその問題がありました。 Proxy = nullを設定してみてください。
WebClient wc = new WebClient();
wc.Proxy = null;
デフォルトでは、WebClient、WebRequestは使用するプロキシをIE設定から決定します。実際のリクエストが送信されるまでに5秒程度の遅延が発生することがあります。
これは、HTTPバインディングを使用するWCFサービスを含む、WebRequestを使用するすべてのクラスに適用されます。通常、この静的コードはアプリケーションの起動時に使用できます。
WebRequest.DefaultWebProxy = null;
ここからWiresharkをダウンロード http://www.wireshark.org/
ネットワークパケットをキャプチャし、「http」パケットをフィルタリングします。すぐに答えが得られるはずです。
設定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は必要ありません。
Wiresharkのもう1つの代替手段(これも無料)は Microsoft Network Monitor です。
IE設定([接続]タブ-LAN設定)で自動プロキシ設定をオンにすると、一部のワークステーションでWebClientが遅くなる場合があります。
テストに使用しているブラウザは何ですか?
デフォルトを使用してみてくださいIEインストール。System.Net.WebClientはローカルIE設定、プロキシなどを使用します。
WebClientのダウンロードが非常に遅いもう1つの原因は、ダウンロード先のメディアです。 USBキーのような遅いデバイスの場合、ダウンロード速度に大きな影響を与える可能性があります。別のドライブからこのUSBに5MB /秒でファイルをコピーできたとしても、HDDに6MB /秒、USBキーに700kb /秒でダウンロードできました。 wgetは同じ動作を示します。これもここで報告されます:
https://superuser.com/questions/413750/why-is-downloading-over-usb-so-slow
したがって、これがシナリオである場合、代替ソリューションは、最初にHDDにダウンロードし、ダウンロードの完了後に低速のメディアにファイルをコピーすることです。
.NET Webリクエストについて本質的に遅いものはありません。そのコードは問題ないはずです。私は定期的にWebClient
を使用しており、非常に高速に動作します。
各方向のペイロードの大きさはどれくらいですか?ばかげた質問かもしれませんが、それは単に帯域幅の制限ですか?
IMOで最も可能性が高いのは、Webサイトがスピンダウンしていて、URLにアクセスしたときにWebサイトの応答が遅いことです。これは、クライアントの責任ではありません。何らかの理由でDNSが遅い(その場合、IPを「ホスト」ファイルにハードコードできる)か、途中のプロキシサーバーが遅い可能性もあります。
Webサイトがあなたのものではない場合、それらが異常な使用を検出しており、意図的にスクレイパーに迷惑をかけるために遅延を挿入している可能性もあります。
私はFiddler(無料のシンプルなWebインスペクター)を入手して、タイミングを調べます。