欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
新博客系统功能更新上线 在CodeIgniter4中实现文件下载权限验证并利用nginx高效处理
晴天  C#同步代码中调用async异步方法.Result等待导致阻塞死锁deadlock的问题
[ 发布日期:11个月前 (12-17) ]   [ 来自:本站原创 ] [分类:C# .Net编程]
在 UI界面或者ASP.NET的同步代码中调用async的异步代码时如果async和task.Result混用会出现线程被阻塞锁死deadlock的情况。
导致死锁的例子代码:
public static async Task<string> GetWebPageAsync(string uri)
{
  //这里的 client 是全局初始化的 HttpClient 对象
    return  = await client.GetStringAsync(uri);
}

public void Button1_Click(object sender, EventArg e)
{
  var webTask = GetWebPageAsync("_get_url_");
  textBox1.Text = webTask.Result;
}



阻止死锁的两种办法:


一、使用 ConfigureAwait(false)
public static async Task<string> GetWebPageAsync(string uri)
{
  //这里的 client 是全局初始化的 HttpClient 对象
    return  = await client.GetStringAsync(uri).ConfigureAwait(false);
}


默认情况下,当您使用async/await时,它将在开始请求的原始线程上继续运行(状态机)。但是,如果当前另一个长时间运行的进程已经接管了该线程,那么你就不得不等待它完成。要避免这个问题,可以使用ConfigureAwait的方法和false参数。当你用这个方法的时候,这将告诉Task它可以在任何可用的线程上恢复自己继续运行,而不是等待最初创建它的线程。这将加快响应速度并避免许多死锁。

但是,当使用此方法后,线程同步上下文将丢失,从而转变成异步操作,如果在之后继续操作界面元素等,会提示线程不安全。


二、使用 异步Async 方法进行调用:
public async void Button1_Click(object sender, EventArg e)
{
  var webTask = GetWebPageAsync("_get_url_");
  textBox1.Text = webTask.Result;
}

引用通告地址 (0):
复制引用地址https://www.rickw.cn/trackback/310
复制引用地址https://www.rickw.cn/trackback/310/GBK
[ 分类:C# .Net编程  | 查看:762 ]

暂时没有评论,快来发表一个评论吧。
发表评论
作者:   用户:[访客] 
评论:

表  情
禁止表情 | 禁止UBB | 禁止图片 | 识别链接
对不起,你没有权限上传附件!
验证:
 
PoweredBy R-Blog V1.00 © 2004-2024 WWW.RICKW.CN, Processed in second(s) , 7 queries    京ICP备17058477号-5