我应该如何在我的业务/服务/应用程序层之间使用异步等待

时间:2016-06-16 07:25:07

标签: c# asp.net-mvc asynchronous async-await

现在我的方法看起来像这样。

业务中的ProductManager类

;with allRecords as 
(
   -- query fetching all the records with many joins
)
select *, c.totalRecords from allRecords 
cross join (select count(*) as totalRecords from allRecords) c

服务中的ProductService类。

public static async Task<List<ProductItem>> GetAllProducts()
{
    var context = GetMyContext();
    return await context.Products.select(x => 
    new ProductItem{ //create item})
    .ToListAsync();
}

应用程序中的ProductController。

public async Task<List<ProductItem>> GetAllProducts()
{
  return await ProductManager.GetAllProducts();
}

此应用程序使用率很高, 这样做完全错了吗? 我应该等待每一种方法吗? 每次调用await时都会启动一个新线程吗?

2 个答案:

答案 0 :(得分:4)

  

这个应用程序的使用率很高,这样做完全错了吗?

没有;它对我来说很好。

  

我应该等待每一种方法吗?

是。在您输入第一个await(在ProductManager中)后,其来电者应为await,其来电者为await,依此类推,直至控制器行动方法。 async的这种“增长”是完全自然的;在关于异步最佳实践的MSDN文章中,它被称为“async all the way”。

  

每次调用await时都会启动一个新线程吗?

没有。 Await是关于释放线程,而不是使用更多线程。我的博客上有一个async intro,其中介绍了asyncawait的工作原理。

答案 1 :(得分:1)

await只是等待某事完成。如果您不需要方法中的任务结果,则无需等待它。 GetAllProducts应该只返回ToListAsync的结果。

public static Task<List<ProductItem>> GetAllProducts()
{
    var context = GetMyContext();
    return context.Products
                  .Select(x => new ProductItem{ //create item})
                  .ToListAsync();
}

async/await增加了一些开销,因为编译器必须生成一个存储原始同步上下文的状态机,等待等待的任务完成,然后恢复原始同步上下文。

在不需要处理任务结果的方法上添加async/await只会增加开销。事实上,有一些Roslyn分析器可以检测并修复这个问题