Async / await在深层嵌套的方法层次结构中

问题描述 投票:3回答:1

如果要在调用层次结构中深入实现异步方法,最佳做法(或最佳建议的做法)是使所有父对象同步吗?

我完全理解控制流如何在异步方法中移动,但是互联网上的大多数示例只显示了一种方法。我感兴趣的是如何在深度嵌套的调用层次结构中使用async / await。

例如,如果您有以下情况会发生什么:

void ControllerMethod() // Root method
{
     ServiceA_MethodOne();
}

// In another place in code
void ServiceA_MethodOne() 
{
     ServiceB_MethodOne();
}

// In another place in code
async Task<List<Product>> ServiceB_MethodOne()
{
     var data = await ctx.Products.ToListAsync();
     // some code here works with data.
}

这似乎主要是因为你想在一个深度嵌套的子方法中异步获取Products,所有的父方法现在必须标记为异步(我没有在上面的例子中将父节点标记为async,用于此示例)

这是正确的假设吗?

现在,我知道GetAwaiter().GetResult(),它实际上可以做到这一点:

void ControllerMethod() // Root method
{
     ServiceA_MethodOne();
}

// In another place in code
void ServiceA_MethodOne() 
{
     ServiceB_MethodOne().GetAwaiter().GetResult();
}

// In another place in code
async Task<List<Product>> ServiceB_MethodOne()
{
     var data = await ctx.Products.ToListAsync();
     // some code here works with data.
}

这将是将async基本“封装”到一个方法中的一种方法。但是在很多文章/教程中,这是不受欢迎的(并且背后有有效但尚未理解的技术解释)

所以更一般地总结一下这个问题:当你在一个方法上使用async / await时,你的整个父调用者层次结构,从调用你的方法的直接父类开始,一直到root方法(你的调用者没有控制权) over),实现为异步方法?

c# asynchronous async-await
1个回答
2
投票

经验法则是async all the way。这并不一定意味着您需要使用async关键字。您也可以返回您收到的相同任务。

void ControllerMethod() // Root method
{
     return ServiceA_MethodOne().GetAwaiter().GetResult();
}

// In another place in code
Task ServiceA_MethodOne() 
{
     return ServiceB_MethodOne();
}

// In another place in code
async Task<List<Product>> ServiceB_MethodOne()
{
     var data = await ctx.Products.ToListAsync();
     // some code here works with data.
}

如果可能的话,尝试使root方法异步也很重要。 ASP.NET MVC支持异步操作。如果您正在编写控制台应用程序而您正在使用C#7,那么您也可以使Main方法异步。

© www.soinside.com 2019 - 2024. All rights reserved.