Почему асинхронный метод не возвращает ожидаемое немедленно?
Я думал, что это разумный шаблон для асинхронного вызова WebClient DownloadData в обработчике событий:
private async void button1_Click(object sender, EventArgs e)
{
WebClient wc = new WebClient();
//wc.Proxy = null;
byte[] bytes = await wc.DownloadDataTaskAsync("http://www.google.com");
label1.Text = Encoding.ASCII.GetString(bytes);
}
Но я нахожу блоки DownloadDataTaskAsync примерно за 5 секунд до возвращения (если только не wc.Proxy = оператор null раскомментирован). Какой смысл в том, чтобы метод был ожидаемым, если он может по своей прихоти выполнить нетривиальную работу, даже не возвращая задачу?
- видимому, это означает, чтобы быть безопасным я хотел и не вызов метода xAsync как выше но вместо этого всегда следует заворачивать их в задание.Беги() сам, чтобы убедиться. Или нет?
2 ответа:
Это известная проблема с
WebClient
/HttpWebRequest
: прокси-серверы и DNS-запросы всегда выполняются синхронно. Это ошибка, но Microsoft в значительной степени решила не исправлять ее по причинам обратной совместимости.Первое, что я бы рекомендовал, - это использовать
HttpClient
. Если это не работает, и вам нужна асинхронность, то вы можете обернуть вызов вTask.Run
.
Получается, что WebClient.DownloadDataTaskAsync вызывает HttpWebRequest.BeginGetResponse
MSDN указывает:
Метод BeginGetResponse требует некоторых синхронных задач настройки, чтобы полное (разрешение DNS, обнаружение прокси и подключение к сокету TCP, например) до того, как этот метод станет асинхронным. в результате, этот метод никогда не должен вызываться в потоке пользовательского интерфейса потому что это может занять значительное время (до нескольких минут в зависимости от настроек сети) для завершения начального синхронного задачи установки до того, как возникнет исключение для ошибки или метод преуспевает.
Http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse(v=vs. 110).aspx
К сожалению, документация MSDN для WebClient.DownloadDataTaskAsync говорит:
Эта операция не блокируется.
Что, похоже, не совсем верно.