【问题标题】:Can I just put async at the top level (service layer) in C#? [closed]我可以将异步放在 C# 的顶层(服务层)吗? [关闭]
【发布时间】:2016-07-06 00:27:42
【问题描述】:

我有一个分层架构,通常将尝试/捕获、日志记录和现在的异步等内容放在顶级服务层,因此我的域代码和存储库是同步编写的,然后我用等待任务将调用包装在我的服务层中.run 这样我就可以将异步命名和逻辑保留在一层中。这个可以吗?或者是否有理由在所有子方法/较低层中也有异步?它实际上会产生更多线程还是仍然只有 1 个异步线程来发挥作用?

如果这没有问题,我有一个问题,在我的存储库中我需要使用 HttpClient,但它只有异步方法,迫使我在我不想使用的架构中使用 async lower。有没有办法在没有等待/异步的情况下调用这些方法,然后在更高层的方法(在我的服务层中)仍然包装在 task.run 中而不阻塞?基本上我不希望任何方法在我的存储库中是异步的,而是希望它们在我的服务层中,它调用存储库和其他域方法。

【问题讨论】:

  • 在方法的实现中不要使用Task.Run;而是使用 Task.Run 调用方法(来自here)。
  • 在他的 blog article 中,Stephen Cleary 提出了一些您可能会感兴趣的好观点。
  • 你为什么首先使用异步?这是一个 Web 服务器场景,对吧?
  • 我的意思是为什么异步而不是同步。这是一个网络服务器场景?
  • 你最好在programmers.stackexchange.com问这个问题

标签: c# .net asynchronous async-await


【解决方案1】:

这样好吗?

不,not ok

根据 Stephen Cleary 一系列写得很好的博文:

一开始就引入了(至少)四个效率问题 您在 ASP.NET 中将 await 与 Task.Run 一起使用:

  • 额外(不必要的)线程切换到 Task.Run 线程池 线。同样,当该线程完成请求时,它必须 输入请求上下文(这不是实际的线程切换,而是 确实有开销)。
  • 创建了额外的(不必要的)垃圾。 异步编程是一种权衡:你得到了增加 以更高的内存使用为代价的响应能力。在这种情况下, 您最终会为异步操作创建更多垃圾 完全没有必要。
  • 抛出 ASP.NET 线程池启发式 通过 Task.Run “意外”借用线程池线程关闭。我不 在这里有很多经验,但我的直觉告诉我, 如果意外任务真的很短,启发式算法应该可以很好地恢复 如果意外任务持续时间更长,也不会优雅地处理它 超过两秒。
  • ASP.NET 无法提前终止请求, 即,如果客户端断开连接或请求超时。在里面 同步情况下,ASP.NET 知道请求线程并可以中止它。 在异步情况下,ASP.NET 不知道辅助 线程池线程“用于”该请求。有可能解决这个问题 通过使用取消标记,但这超出了本文的范围 博文。

这应该足以提醒您重新考虑您的方法。 “您将 Task.Run 用于异步包装器的事实是代码异味”

是否有理由在所有子方法/较低层中也有async

是的,etiquette

它实际上会产生更多线程还是仍然只有 1 个异步线程来发挥作用?

There is no thread.

我建议阅读best practices

Stephen Toub 补充阅读。

【讨论】:

  • 感谢@david-pine 的回复。但是,现在您对 ASP.NET Web API 背后的任何操作以及(服务、域、存储库)下的所有层都使用 async 让我产生疑问。除非我尝试 A)解锁 UI 线程或 B)在任务数组中运行多个操作,否则使用它真的有好处吗?我的 Task.Run 包装器正在创建 1 个上下文切换,而如果我让异步流动并失去请求线程断开连接的好处,我可能会有很多切换和性能损失。为什么不直接阻止 Web API 方法调用背后的所有内容?
  • 当然,在 Web API 中使用 async 是它的理想用例。一方面,您处于 I/O 绑定操作的上下文中,从某个数据存储中提取数据并通过网络返回。这两个都是瓶颈,可能会影响性能。您应该在这里使用“一直异步”。 stackoverflow.com/a/23928922/2410379stackoverflow.com/a/22178599/2410379stackoverflow.com/a/16841486/2410379
  • 谢谢@david-pine。因此,如果我理解正确,最好将 async/await 用于 I/O 绑定操作,但不适合对这些操作使用 Task.Run。对吗?
  • @SeanMerron 正确。
  • 感谢@david-pine 抽出宝贵时间为我解惑!我真的很感激,是时候进行一些代码更改了:-)
猜你喜欢
  • 2018-02-10
  • 2011-02-05
  • 2012-12-28
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 2012-06-12
相关资源
最近更新 更多