我对ASP.Net MVC 4+中的异步控制器和动作有一个快速的问题(使用返回任务的async / await编程模型)。 即使下划线操作不是IO Bound(例如慢速Web服务或网络通信)并且可以是CPU绑定,如果我的所有操作都是异步的,我会冒什么风险。我的意思是无论代码是什么,我的所有动作都是异步的。我希望我很清楚。
由于同步上下文开销或任何其他可能有很多同时用户的公共网站的显着开销会导致性能问题吗?
感谢您的未来答案。
答案 0 :(得分:4)
即使下划线操作不是IO Bound(例如慢速Web服务或网络通信)并且可以是CPU绑定,如果我的所有操作都是异步的,我会冒什么风险。
这正是不想要做的事情。
考虑同步操作会发生什么:请求进来,ASP.NET为该请求分配一个线程,该线程执行该操作。当操作完成时,同一个线程发送响应。
现在考虑如果将操作的CPU限制工作“卸载”到线程池(例如,Task.Run
)会发生什么。请求进来,ASP.NET为该请求分配一个线程,线程开始执行该操作。当线程命中Task.Run
时,它会从线程池中分配另一个线程来执行CPU绑定的代码。然后异步操作方法命中该任务的await
,因此原始线程返回到ASP.NET运行时。然后其他线程完成工作并继续发送响应。
因此,如果您有一个将CPU绑定工作推送到线程池的异步操作,那么您正在为每个请求执行 more 工作。您应该从不在ASP.NET上执行此操作。
我更详细地解释了这一点on my blog。
答案 1 :(得分:1)
我不认为你会遇到一个简单的应用程序的任何问题,因为异步工作程序正在运行具有极限线程数的线程池。但是您可能遇到的情况是客户端HTTP线程正在等待asyn响应,并且它超过了网络网关超时。例如,亚马逊ELB有60秒超时。因此,在异步任务仍在运行时,客户端可以断开连接。如果这种情况发生了很多,那么你最终可能会遇到很多异步任务在运行和完成而没有客户端响应。这将是一个不幸的条件,因为您的客户端没有获取数据,您的服务器无法正常工作。
我要考虑的一件事是你是否需要异步调用。我建议调整您的服务调用并确保它们足够快以解决负载问题,而不是将前端异步作为延迟的解决方法。例如,使用缓存。只是一个建议。
希望它有所帮助。