2016-05-05 3 views
1

Я написал метод, использующий HttpClient:HttpClient.GetStringAsync блокировки в консоли приложения

private static async Task<string> DownloadString(string url) 
{ 
    var uri = new Uri(url); 

    using (var client = new HttpClient()) 
    { 
     HttpRequestHeaders headers = client.DefaultRequestHeaders; 
     headers.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); 
     headers.AcceptEncoding.ParseAdd("gzip, deflate"); 
     headers.AcceptLanguage.ParseAdd("en-US,en;q=0.5"); 
     headers.Connection.ParseAdd("keep-alive"); 
     headers.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0"); 
     headers.Host = uri.Host; 

     return await client.GetStringAsync(uri).ConfigureAwait(false); 
    } 
} 

Тогда я вызываю его в Main методе консольное приложение так:

Console.WriteLine("Downloading"); 
string dom = DownloadString("http://www.shaanig.org/f8/index1.html").Result; 
Console.WriteLine(dom); 

Все произведения отлично, если у меня есть подключение к Интернету, или если он работает, пока у меня нет подключения к Интернету (в этом случае он генерирует исключение). Но если я отключу свой интернет, пока он загружается, он просто висит там. Без исключений. Он просто висит.

Может кто-нибудь объяснить мне, что здесь происходит? И как я могу это исправить?

+0

определить «зависает»? –

+0

взгляните на этот ответ http://stackoverflow.com/questions/20696320/checking-internet-connection-with-httpclient –

+0

@DavidHaim, пытаясь определить это, я обнаружил, что он бросает после колоссальных 100 секунд. –

ответ

1

Я думаю, вы должны использовать свойство HttpClient.Timeout.

В HttpClient конструкции, вы можете использовать:

var client = new HttpClient() 
{ 
    Timeout = TimeSpan.FromMilliseconds(200) 
}; 
+0

http-запросы уже имеют тайм-аут по умолчанию, установленный самой .Net. Это не имеет значения –

+0

@DavidHaim, похоже, что оно по умолчанию 100 секунд. Не знал, что это так долго ... –

0

Вы бы лучше изменить его от статического к классу экземпляра, а затем запустить его в отдельном потоке. У вас возникнут проблемы при использовании статических классов и нескольких потоков.

Во-вторых, почему вы звоните ConfigureAwait здесь:

return await client.GetStringAsync(uri).ConfigureAwait(false); 

Вы используете асинхронной/ОЖИДАНИЕ шаблон, так что вам не нужно использовать.

+0

'ConfigureAwait' - лучшая практика, если я не хочу фиксировать контекст синхронизации. Я сомневаюсь, что метод экземпляра будет работать. Кроме того, если это асинхронно, зачем мне начинать новый поток? –

1

при попытке определить это, я обнаружил, что он бросает после колоссальных 100 секунд.

Я закрыл его вниз после того, как 1 секунды

так, там не ошибка/повесить.
в Windows, .Net использует базовый собственный API WinHttp для выполнения http-запросов.

, если мы посмотрим на .Net Code which calls WinHttp мы видим, что

private TimeSpan _connectTimeout = TimeSpan.FromSeconds(60); 
private TimeSpan _sendTimeout = TimeSpan.FromSeconds(30); 
private TimeSpan _receiveHeadersTimeout = TimeSpan.FromSeconds(30); 
private TimeSpan _receiveDataTimeout = TimeSpan.FromSeconds(30); 

если заблокировать интернет около одной секунды после того, как запрос начался, это займет около 30 ~ 60 секунд для того, чтобы тайм-аут, чтобы быть уволены ,

+0

Это действительно 100 секунд. 'Значение по умолчанию - 100 000 миллисекунд (100 секунд) .' –

Смежные вопросы