System.Net.WebClient неоправданно медленный
При использовании метода System.Net.WebClient.DownloadData() я получаю неоправданно медленное время отклика.
При получении URL-адреса с использованием класса WebClient в .NET требуется около 10 секунд, прежде чем я получу ответ, в то время как та же страница загружается моим браузером менее чем за 1 секунду.
И это с данными размером 0,5 КБ или меньше.
Запрос включает параметры POST/GET и заголовок пользовательского агента, если это может вызвать проблемы.
Я еще не пробовал, если другие способы загрузки данных в .NET вызывают у меня те же проблемы, но я подозреваю, что мог бы получить аналогичные результаты. (У меня всегда было чувство, что веб-запросы в .NET необычно медленные...)
Что может быть причиной этого?
Изменить:
Япопытался сделать то же самое, используя 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);
}
Ответы
Ответ 1
У меня была эта проблема с WebRequest. Попробуйте установить Proxy = null;
WebClient wc = new WebClient();
wc.Proxy = null;
По умолчанию WebClient, WebRequest пытается определить, какой прокси использовать из настроек IE, иногда это приводит к задержке в 5 секунд до отправки фактического запроса.
Это относится ко всем классам, использующим WebRequest, включая службы WCF с привязкой HTTP.
В общем случае вы можете использовать этот статический код при запуске приложения:
WebRequest.DefaultWebProxy = null;
Ответ 2
Загрузить Wireshark здесь http://www.wireshark.org/
Захват сетевых пакетов и фильтрация пакетов "http".
Он должен дать вам ответ сразу.
Ответ 3
Установка WebRequest.DefaultWebProxy = null;
или client.Proxy = null
ничего не сделала для меня, используя Xamarin на iOS.
Я сделал две вещи, чтобы исправить это:
Я написал функцию downloadString, которая не использует WebRequest и System.Net:
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 "";
}
}
Это все еще медленно с управляемым HttpClient.
Итак, во-вторых, в сообществе Visual Studio для Mac, щелкните правой кнопкой мыши свой проект в решении → Параметры → , чтобы для реализации HttpClient было выбрано NSUrlSession, а не Managed.
Снимок экрана: установите реализацию HttpClient на NSUrlSession вместо управляемого
Managed не полностью интегрирован в iOS, не поддерживает TLS 1.2 и, следовательно, не поддерживает стандарты ATS, установленные по умолчанию в iOS9+, см. здесь:
https://docs.microsoft.com/en-us/xamarin/ios/app-fundamentals/ats
При обоих этих изменениях загрузка строк всегда происходит очень быстро (& lt; & lt; 1s).
Без обоих этих изменений при каждой второй или третьей попытке downloadString занимало более минуты.
Только к вашему сведению, есть еще одна вещь, которую вы можете попробовать, хотя это больше не нужно:
//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.
Ответ 4
По сути дела нет веб-запросов .NET; этот код должен быть прекрасным. Я регулярно использую WebClient
, и он работает очень быстро.
Насколько велика полезная нагрузка в каждом направлении? Может быть, глупый вопрос, но это просто ограничения пропускной способности?
ИМО, скорее всего, это то, что ваш веб-сайт развернулся, и когда вы нажимаете на URL-адрес, веб-сайт медленно реагирует. Это не ошибка клиента. Также возможно, что по какой-либо причине DNS медленный (в этом случае вы можете жестко закодировать IP-адрес в своем файле "hosts" ) или что некоторый прокси-сервер посередине медленный.
Если веб-сайт не принадлежит вам, возможно также, что они обнаруживают атипичное использование и намеренно вводят задержку, чтобы раздражать скребки.
Я бы схватил Fiddler (бесплатный, простой веб-инспектор) и посмотрел на тайминги.
Ответ 5
Еще одна альтернатива (также бесплатная) для Wireshark Microsoft Network Monitor.
Ответ 6
Какой браузер вы используете для тестирования?
Попробуйте использовать установку IE по умолчанию. System.Net.WebClient использует локальные настройки IE, прокси и т.д. Может быть, это искалечено?
Ответ 7
WebClient может быть медленным на некоторых рабочих станциях при настройке параметров автоматического прокси-сервера в настройках IE (вкладка "Подключения" - настройки локальной сети).
Ответ 8
Другой причиной чрезвычайно медленных загрузок WebClient является носитель назначения, который вы загружаете. Если это медленное устройство, например USB-ключ, это может значительно повлиять на скорость загрузки. На мой жесткий диск я мог загружать с 6 Мбайт/с, на мой USB-ключ, всего 700 кб/с, хотя я могу копировать файлы на этот USB с 5 Мбайт/с с другого диска. wget показывает то же поведение. Это также сообщается здесь:
https://superuser.com/info/413750/why-is-downloading-over-usb-so-slow
Итак, если это ваш сценарий, альтернативным решением является загрузка на жесткий диск сначала, а затем копирование файлов на медленный носитель после завершения загрузки.