【问题标题】:Does async in the data layer require the entire call stack to be async as well?数据层中的异步是否也要求整个调用堆栈也是异步的?
【发布时间】:2017-01-24 21:08:50
【问题描述】:

如今,数据层与 DB 进行异步交互是很常见的:

public async Task<Customer> GetCustomer(int id)
{
  using (db = new AppDbContext())
  {
    return await db.Customers.FindAsync(id);
  }
}

使用这种技术,据我了解,所有调用方法,一直到 UI 层,也必须使用 async 关键字定义。因此,您最终会得到一个应用程序,其中最终与 DB 交互的每个方法或函数都是异步方法。

这似乎非常混乱,并且“污染”了所有应用程序层,因为他们知道数据层内的实现细节。

我是误会了什么还是这只是一个人必须做的事情?

【问题讨论】:

  • 我看不到您如何将“我稍后返回客户信息的承诺”和“我立即返回客户信息”之间的区别视为实现细节。您不需要在任何地方都使用async 上下文关键字,但它确实 可以一直同步或一直异步。我能想到的唯一例外是您组合多个异步操作来查询多个源,然后同步返回一个复合数据结构。
  • "Am I misunderstanding something" - 是的。代码应该是“一直异步”。这个想法是顶级应用程序层可以管理在更深层中具有异步组件的操作,它不需要知道。组件本身仍然返回相同的信息,并且仍然封装它们如何到达该信息。唯一的区别是他们何时返回它,这是一个架构考虑而不是实现细节。
  • Jon - 这是一个实现细节,因为我这样做的唯一原因是提高可伸缩性。 (我考虑的是 Web 应用程序,而不是胖客户端,第二个原因可能是 UI 响应能力。)如果不对所有层产生显着影响,似乎没有办法实现这一点。我只是希望它没有。
  • @Roger:异步操作不是实现细节。实现细节可能是强制您重新构建代码以允许异步操作的原因,但理想情况下,重组本身应该在操作可能同步或可能不同步的环境中无论如何都发生。我不明白你为什么要在你的应用层不知道的情况下执行异步操作,这似乎是你不需要的问题的秘诀。应用程序主机负责管理同步,因此它应该知道异步操作。

标签: c# .net asynchronous architecture async-await


【解决方案1】:

我是误会了什么,还是这只是一个人必须做的事情?

不,你是对的。这只是你必须做的事情。

这似乎非常混乱,并且“污染”了所有应用程序层,因为他们知道数据层内的实现细节。

是的,这些实现细节确实会泄漏,这很不幸。这只是绝大多数计算机语言如何工作的现实。

我倾向于将async 详细信息与IDisposable 详细信息进行比较。如果一个类实现了IDisposable,那么它的包含(拥有)类应该等等。但是一个类是否拥有资源应该确实是一个实现细节。

【讨论】:

    猜你喜欢
    • 2020-10-21
    • 2021-01-06
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    相关资源
    最近更新 更多