我有一个分层架构,通常将诸如 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 补充阅读.