异步并等待调用者不是异步但调用方法是异步的地方

时间:2018-10-11 12:35:22

标签: c# asynchronous async-await task

任何人都可以向我解释在以下情况下会发生什么情况:

public int? getValue()
{
    return GetIntValue().Result;
}

public async Task<int?> GetIntValue()
{
    return await getId();
}

public async Task<int?> getId()
{
    return (await Context.Users.FirstOrDefaultAsync())?.AssignedUserId;
}

,如果这种情况有所不同:

public int? getValue()
{
    return getId().Result;
}

基本上,我想知道在这两种情况(或两种情况)下,这里的等待是否会导致执行继续到结果返回之前?如果它们不同,为什么它们会不同?

2 个答案:

答案 0 :(得分:4)

getId().Result;是一个阻塞调用,可能会导致死锁情况。当前执行线程将一直阻塞,直到调用该函数返回为止。

另一方面,使用async/await方法不会阻塞。处理该调用的线程将停止并且可用于处理另一个调用。然后,当您的函数调用完成时,结果将由线程池中的另一个线程处理。

现在,上述阻塞调用将如何影响您的应用程序,这取决于您的应用程序类型。例如,如果我们谈论的是Windows Forms应用程序或WPF应用程序,并且此代码将在UI线程上执行,则您的表单将冻结,直到完成此调用为止。另一方面,如果这是一个ASP.NET应用程序,并且您有许多请求到达服务器,则可能导致ASP.NET线程用尽,其目的是处理服务器接收到的请求。显然,这将导致应用程序不响应新请求,直到收到的某些请求服务器获得响应为止。

关于死锁情况,请查看此question,尤其是第一个答案。在这里,您将找到有关该主题Don't Block on Async Code的出色文章的链接。

答案 1 :(得分:0)

这将导致相同的结果,两者都将等待,直到检索到用户为止,这样getValue()方法将返回value且不会返回null。