c# – 即使在Asp.Net流中使用ConfigureAwait(false)后仍然死锁
即使在使用ConfigureAwait(false)之后,我也遇到死锁,下面是示例代码.
根据样本http://blog.stephencleary.com/2012/02/async-and-await.html(#Avoding上下文),这不应该是死锁. 这是我的课: public class ProjectsRetriever { public string GetProjects() { ... var projects = this.GetProjects(uri).Result; ... ... } private async Task<IEnumerable<Project>> GetProjects(Uri uri) { return await this.projectSystem.GetProjects(uri,Constants.UserName).ConfigureAwait(false); } } 这个类来自一个共享库: public class ProjectSystem { public async Task<IEnumerable<Project>> GetProjects(Uri uri,string userName) { var projectClient = this.GetHttpClient<ProjectHttpClient>(uri); var projects = await projectClient.GetProjects(); // code here is never hit ... } 如果我在配置HttpClient调用的共享库中添加ConfigureAwait(false)来等待调用,则可以工作: public class ProjectSystem { public async Task<IEnumerable<Project>> GetProjects(Uri uri,string userName) { var projectClient = this.GetHttpClient<ProjectHttpClient>(uri); var projects = await projectClient.GetProjects().ConfigureAwait(false); // no deadlock,resumes in a new thread. ... } 我一直在浏览所有发现的博客,只有区别我发现ConfigureAwait(false)工作时使用httpClient.AsyncApi()调用! 请帮忙澄清!!! 解决方法
从评论:
我不相信黑魔法,也不应该.始终努力了解当您在代码中使用某些内容时会发生什么. 当等待返回任务或任务< T>的异步方法时,Task.GetAwaiter方法生成的TaskAwaitable将隐含捕获SynchronizationContext. 一旦同步上下文到位并且异步方法调用完成,TaskAwaitable会尝试将继承(其基本上是第一个await关键字之后的其余方法调用)编组到先前捕获的SynchronizationContext(使用SynchronizationContext.Post) .如果调用线程被阻止,等待同一个方法完成,你有一个死锁. 你应该问自己Should I expose synchronous wrappers for asynchronous methods? 99%的答案是否定的.您应该使用同步API,例如WebClient提供的API. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |