是什么导致了僵局



我知道这不是使用正确的形式,但有人能告诉我为什么第一个代码片段有效,而第二个代码片段导致死锁吗?

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

最新更新