c# - 我可以将异步放在 C# 的顶层(服务层)吗?

标签 c# .net asynchronous async-await

<分区>

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

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

最佳答案

Is this OK?

不,not ok .

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

There are (at least) four efficiency problems introduced as soon as you use await with Task.Run in ASP.NET:

  • Extra (unnecessary) thread switching to the Task.Run thread pool thread. Similarly, when that thread finishes the request, it has to enter the request context (which is not an actual thread switch but does have overhead).
  • Extra (unnecessary) garbage is created. Asynchronous programming is a tradeoff: you get increased responsiveness at the expense of higher memory usage. In this case, you end up creating more garbage for the asynchronous operations that is totally unnecessary.
  • The ASP.NET thread pool heuristics are thrown off by Task.Run “unexpectedly” borrowing a thread pool thread. I don’t have a lot of experience here, but my gut instinct tells me that the heuristics should recover well if the unexpected task is really short and would not handle it as elegantly if the unexpected task lasts more than two seconds.
  • ASP.NET is not able to terminate the request early, i.e., if the client disconnects or the request times out. In the synchronous case, ASP.NET knew the request thread and could abort it. In the asynchronous case, ASP.NET is not aware that the secondary thread pool thread is “for” that request. It is possible to fix this by using cancellation tokens, but that’s outside the scope of this blog post.

这足以警告您重新考虑您的方法。 “您正在使用 Task.Run 作为异步包装器这一事实是一种代码味道”

Is there a reason to have async in all the child methods / lower layers as well?

是的,etiquette .

Will it actually spawn more threads or still only be 1 async thread that does the magic?

There is no thread.

我建议阅读 best practices .

Stephen Toub 补充阅读.

关于c# - 我可以将异步放在 C# 的顶层(服务层)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38204979/

相关文章:

c# - 如何在KeyValuePair列表中搜索重复键并删除较早的键值

node.js - Node 异步与同步

C# - 如何缩小 SHA512 的大小

c# - 强制 C# 应用程序在 64 位服务器上以 32 位模式运行

c# - 锁变量应该声明为 volatile 吗?

node.js - Node 生成的子进程何时真正启动?

ios - 在显示数据之前处理异步下载延迟

c# - Entity Framework 4.1 - 使用过滤器覆盖实体 (DBSet)

c# - 如何在开始菜单中为 ClickOnce 应用程序创建卸载链接

.net - 将 C++ printf 格式与 VB .NET 字符串格式相互转换