c# – 即使在Asp.Net流中使用ConfigureAwait(false)后仍然死锁

前端之家收集整理的这篇文章主要介绍了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()调用

请帮忙澄清!!!

解决方法

评论

I was under assumption,once ConfigureAwait(false) is used (any where in the call stack),execution from that point will not cause deadlock.

我不相信黑魔法,也不应该.始终努力了解当您在代码中使用某些内容时会发生什么.

当等待返回任务或任务< T>的异步方法时,Task.GetAwaiter方法生成的TaskAwaitable将隐含捕获SynchronizationContext.

一旦同步上下文到位并且异步方法调用完成,TaskAwaitable会尝试将继承(其基本上是第一个await关键字之后的其余方法调用)编组到先前捕获的SynchronizationContext(使用SynchronizationContext.Post) .如果调用线程被阻止,等待同一个方法完成,你有一个死锁.

你应该问自己Should I expose synchronous wrappers for asynchronous methods? 99%的答案是否定的.您应该使用同步API,例如WebClient提供的API.

原文链接:https://www.f2er.com/csharp/94106.html

猜你在找的C#相关文章