我知道这不是使用正确的形式,但有人能告诉我为什么第一个代码片段有效,而第二个代码片段导致死锁吗?
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = DownloadStringV3("https://www.google.com");
}
public string DownloadStringV3(String url)
{
var resp = new HttpClient().GetAsync(url).Result;
return resp.Content.ReadAsStringAsync().Result;
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = DownloadStringV3("https://www.google.com").Result;
}
public async Task<string> DownloadStringV3(String url)
{
var resp = await new HttpClient().GetAsync(url);
return await resp.Content.ReadAsStringAsync();
}
不同的同步上下文?这正在使用。净4.8
每次await
某个东西,你都会说,我在这里暂时完成了,给其他线程一个执行的机会,然后在异步任务完成后从这里继续。
因此,在您的情况下,await new HttpClient().GetAsync(url)
切换ui线程并等待DownloadStringV3("https://www.google.com").Result
完成,这将永远不会发生,因为我们从不执行return await resp.Content.ReadAsStringAsync()
。
这就是为什么您应该一直异步到根目录,并且永远不要调用Result
。
第一个代码是有效的,因为你阻塞了UI线程,在等待它的时候没有试图切换到另一个线程
要使第二个工作,你需要:
private async void button1_Click(object sender, EventArgs e)
{
// make with try catch sure, you catch any error, async void is special. Better is async Task
textBox1.Text = await DownloadStringV3("https://www.google.com");
}
public async Task<string> DownloadStringV3(String url)
{
var resp = await new HttpClient().GetAsync(url);
return await resp.Content.ReadAsStringAsync();
}