即使在Asp.Net流量使用ConfigureAwait(假)后死锁 [英] deadlock even after using ConfigureAwait(false) in Asp.Net flow

查看:522
本文介绍了即使在Asp.Net流量使用ConfigureAwait(假)后死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我甚至使用后点击僵局 ConfigureAwait(假),下面是样品code。

I'm hitting deadlock even after using ConfigureAwait(false), below is the sample code.

由于每个样品<一个href=\"http://blog.stephencleary.com/2012/02/async-and-await.html\">http://blog.stephencleary.com/2012/02/async-and-await.html (#Avoding上下文),这不应该打到死锁。

As per the sample http://blog.stephencleary.com/2012/02/async-and-await.html (#Avoding Context), this should not have hit dead lock.

这是我的类

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
        ...
}

工作,如果我加ConfigureAwait(假)等待共享库,这里的HttpClient调用时来电:

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(假)一起使用时,与httpClient.AsyncApi()调用!?

I've been going through all blogs found, only difference I find is ConfigureAwait(false) works when used with httpClient.AsyncApi() call!?

请帮忙澄清!

推荐答案

从注​​释:

我下假设,一旦ConfigureAwait(假)时(在调用堆栈中任何地方),从该点执行不会引起死锁。

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

我不相信魔法,你也不应该。总是努力去理解当您在code使用的东西会发生什么。

I don't believe in black magic, and neither should you. Always strive to understand what happens when you use something in your code.

的await 返回异步方法工作任务&LT; T&GT ; ,有的SynchronizationContext TaskAwaitable 正在生成的隐式捕获 Task.GetAwaiter 方法。

When you await an async method that returns a Task or a Task<T>, there is an implicit capture of the SynchronizationContext by the TaskAwaitable being generated by the Task.GetAwaiter method.

一旦同步上下文到位,异步方法调用完成后, TaskAwaitable 试图元帅的延续(这基本上是该方法的休息后先调用的await 关键字)到的SynchronizationContext (使用 SynchronizationContext.Post ),它是previously抓获。如果调用线程被阻塞,等待上相同的方法来完成,你有一个僵局

Once that sync context is in place and the async method call completes, the TaskAwaitable attempts to marshal the continuation (which is basically the rest of the method calls after the first await keyword) onto the SynchronizationContext (using SynchronizationContext.Post) which was previously captured. If the calling thread is blocked, waiting on that same method to finish, you have a deadlock.

您应该问自己我应该公开为异步方法同步包装?的答案是时间 99%没有。您应该使用同步API,比如一个 Web客户端优惠。

You should ask yourself Should I expose synchronous wrappers for asynchronous methods? 99 percent of the time the answer is no. You should use a synchronous API, such as the one WebClient offers.

这篇关于即使在Asp.Net流量使用ConfigureAwait(假)后死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆