C# async await 死锁问题总结
2021-01-19 22:12
标签:base wait方法 form out index result sync href mono 可能发生死锁的程序类型 1、WPF/WinForm程序 2、asp.net (不包括asp.net mvc)程序 死锁的产生原理 对异步方法返回的Task调用Wait()或访问Result属性时,可能会产生死锁。 下面的WPF代码会出现死锁: 下面的asp.net mvc代码也会出现死锁: 以WPF代码为例,事件处理器调用Method1,得到Task对象,然后调用Task的Wait方法,阻塞自己所在的线程,即主线程,直到Task对象“完成”。而返回的Task对象要想“完成”,必须在主线程上执行await之后的代码。而主线程早就处于阻塞状态,它在等待Task对象完成!于是死锁就产生了。 asp.net mvc代码是同样的道理。 如何避免死锁 可以试验一下,下面的代码是不会有问题的: 下面的代码也不会有问题: 下面的却会产生死锁: 为什么在HttpClient的GetStringAsync()返回的Task上访问Resut不会产生死锁,而自己写的代码就出现了死锁? 从mono的HttpClient源代码上,可以找到一些端倪: 所有await 表达式后面,都加了ConfigureAwait (false),如 return await resp.Content.ReadAsStringAsync ().ConfigureAwait (false); 而由Task的msdn文档可以知,ConfigureAwait (false)会指示await之后的代码不在原先的context (可理解为线程)上运行。 这样,问题就迎刃而解了:以最初的WPF代码为例,主线程阻塞,等待Task对象“完成”;Method1被调用100ms后,在另外的线程上执行了await的之后的代码,于是Task对象完成。主线程恢复执行。 把使用HttpClient造成死锁的代码改成如下形式: 可以发现,死锁不会出现了 后话 C# async await 死锁问题总结 标签:base wait方法 form out index result sync href mono 原文地址:https://www.cnblogs.com/sdBob/p/12151013.html private void Button_Click_7(object sender, RoutedEventArgs e)
{
Method1().Wait();
}
private async Task Method1()
{
await Task.Delay(100);
txtLog.AppendText("后续代码");
}
public ActionResult Index()
{
string s=Method1().Result;
return View();
}
private async Taskstring> Method1()
{
await Task.Delay(100);
return "hello";
}
private void Button_Click_8(object sender, RoutedEventArgs e)
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://www.baidu.com/");
string html = httpClient.GetStringAsync("/").Result;
txtLog.AppendText(html);
}
private void Button_Click_8(object sender, RoutedEventArgs e)
{
string html = GetHtml();
txtLog.AppendText(html);
}
private string GetHtml()
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://www.baidu.com/");
return httpClient.GetStringAsync("/").Result;
}
private void Button_Click_8(object sender, RoutedEventArgs e)
{
string html = GetHtml().Result;
txtLog.AppendText(html);
}
private async Taskstring> GetHtml()
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://www.baidu.com/");
return await httpClient.GetStringAsync("/");
}
private void Button_Click_8(object sender, RoutedEventArgs e)
{
string html = GetHtml().Result;
txtLog.AppendText(html);
}
private async Taskstring> GetHtml()
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://www.baidu.com/");
return await httpClient.GetStringAsync("/").ConfigureAwait(false);
}
文章标题:C# async await 死锁问题总结
文章链接:http://soscw.com/index.php/essay/44249.html