如何在不影响上层的情况下使我的存储库异步

时间:2014-02-05 14:52:32

标签: async-await asp.net-mvc-5

我有一个Asp.net MVC 5应用程序:

  • Web UI图层
  • 业务逻辑层
  • 数据存储库图层

它们也按此顺序引用。 UI仅访问业务逻辑和业务逻辑引用存储库。

与99%的应用程序一样,除了调用数据库(或其他I / O昂贵的操作)之外,所有内容都可以并且应该同步执行。这就是为什么我想让数据层异步,但不影响上层,使所有上层调用方法异步(一直到控制器操作)。

这可能吗?

我在想做什么

我在考虑用这种方式改变事物。

数据层方法

public async Task<SomeEntity> GetData()
{
    return await Task.Run<SomeEntity>(() => ...);
}

业务逻辑方法

public SomeEntity GetData()
{
    return this.repo.GetData().Result;
}

问题

这是否有意义,我实际上是否会以异步方式执行代码?

更新

在阅读了Stephen Cleary的博客文章之后,我更清楚地知道整个调用堆栈到底部(分割同步性的数据层)正被数据异步调用拆分,因此所有调用都是堆栈应该是异步和拆分。

如果这种想法是正确的,那么当我这么说时,我的假设是正确的

  

为了不将整个同步调用堆栈转换为异步,我们应该创建一个可以异步工作的独立线程,我们的同步线程会使用它。

问题2

这个假设是否正确,如果是,这是保持某些部分同步的唯一方法吗?

2 个答案:

答案 0 :(得分:4)

  

与99%的应用程序一样,除了调用数据库之外,所有内容都可以并且应该同步执行。

完全没有。任何基于I / O的东西都应该是异步的。

因此,数据层执行数据库I / O,并且应该是异步的。

业务逻辑层使用基于I / O的数据层,并且应该是异步的。

UI层使用业务逻辑层,它是基于I / O的,应该是异步的。

当然,只有那些实际上基于I / O的方法应该是异步的;其余的应该是同步的。但我发现在数据访问量很大的应用程序中,它们几乎完全是异步

  

这是否有意义,我实际上是否会以异步方式执行代码?

没有。抱歉,您永远不应该在Task.Run中包装异步代码并在ASP.NET应用程序中阻止它。所有这一切都会耗尽超过处理请求所需的线程。保持全部同步比使用多个线程保持同步更好。

在ASP.NET上, 允许异步传播所有层,以便拥有异步操作/处理程序(以及随之而来的所有好处,即可伸缩性)。< / p>

答案 1 :(得分:0)

在此庄园中将async与async混合可能很危险,因为它会引发死锁。 Stephen Cleary在这里解释得非常好:

http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html