控制台应用程序中的HttpClient.GetStringAsync阻塞

时间:2016-05-05 11:05:10

标签: c# dotnet-httpclient

我使用HttpClient编写了一个方法:

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);

如果我有互联网连接,或者如果它在没有互联网连接的情况下运行,那么一切正常(在这种情况下,它会引发异常)。但是,如果我在下载时断开我的互联网,它就会挂在那里。没有例外。它只是挂起。

有人可以向我解释这里发生了什么吗?我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

我认为你必须使用HttpClient.Timeout属性。

在HttpClient构造中,您可以使用:

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

答案 1 :(得分:1)

  

在尝试定义时,我发现它在高达100秒后抛出。

     

我在1秒后关闭它

所以,没有错误/挂起。
在Windows上,。Net使用底层的本地WinHttp API来发出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秒才能触发超时。

答案 2 :(得分:0)

最好将它从静态类更改为实例类,然后在单独的线程上运行它。使用静态类和多个线程时会遇到麻烦。

其次,为什么要在这里调用ConfigureAwait:

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

您正在使用async / await模式,因此您无需使用它。