C# 控制台应用程序中的HttpClient.GetStringAsync阻塞
我使用C# 控制台应用程序中的HttpClient.GetStringAsync阻塞,c#,dotnet-httpclient,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
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);
}
}
如果我有互联网连接,或者它在我没有互联网连接的情况下运行(在这种情况下,它抛出一个异常),所有这些都可以正常工作。但是,如果我在下载时断开互联网,它就会挂在那里。没有例外。它只是挂着
有人能给我解释一下这里发生了什么事吗?我该如何解决这个问题呢?我认为您必须使用HttpClient.Timeout属性 在HttpClient构造中,您可以使用:
var client = new HttpClient()
{
Timeout = TimeSpan.FromMilliseconds(200)
};
最好将其从静态类更改为实例类,然后在单独的线程上运行。使用静态类和多线程时会遇到麻烦 其次,您为什么在这里调用ConfigureWait:
return await client.GetStringAsync(uri).ConfigureAwait(false);
您使用的是异步/等待模式,因此不需要使用它
当我试图定义它的时候,我发现它会在100秒后抛出
我在大约1秒钟后关闭了它
因此,没有bug/hang。在Windows上,.Net使用底层的本机
WinHttp
API发出http请求
如果我们看一看,就会发现
private TimeSpan _connectTimeout = TimeSpan.FromSeconds(60);
private TimeSpan _sendTimeout = TimeSpan.FromSeconds(30);
private TimeSpan _receiveHeadersTimeout = TimeSpan.FromSeconds(30);
private TimeSpan _receiveDataTimeout = TimeSpan.FromSeconds(30);
如果您在请求开始后大约1秒阻止internet,则需要大约30~60秒才能触发超时。看看这个答案@DavidHaim,在尝试定义它时,我发现它会在惊人的100秒后触发。@emperoaiman当您关闭interenet时,请求停止后大约过了多少秒?@DavidHaim我在大约1秒后关闭了它。http请求已经有了由.Net本身设置的默认超时。。这没有问题meaning@DavidHaim,看起来它默认为100秒。我不知道这么长…
configurewait
是最好的做法,如果我不想捕获同步上下文。。我怀疑使用实例方法是否有效。另外,如果它是异步的,为什么我要启动一个新线程呢?实际上是100秒<代码>默认值为100000毫秒(100秒)。
private TimeSpan _connectTimeout = TimeSpan.FromSeconds(60);
private TimeSpan _sendTimeout = TimeSpan.FromSeconds(30);
private TimeSpan _receiveHeadersTimeout = TimeSpan.FromSeconds(30);
private TimeSpan _receiveDataTimeout = TimeSpan.FromSeconds(30);