如何在MVC中耗时的操作中使用AsyncController或Task或Thread?

sup*_*tsy 5 asp.net-mvc async-await asp.net-mvc-4

我有一个简单但耗时的操作:当用户单击一个按钮时,它执行数据库密集型操作,将记录从导入表处理到多个其他表,一次一个导入记录.我有一个带有触发操作的按钮的视图,在操作结束时会显示一个报告.

我正在寻找通知用户正在处理操作的方法.这是我喜欢的解决方案.

我一直在网上阅读有关MVC中异步操作的内容.我发现有很多链接说如果你的进程受CPU约束,那就坚持使用同步操作了.数据库相关进程是否被视为CPU绑定?

此外,如果我得到了异步操作路由,我应该使用AsyncController,如此处所述,或者只使用我在上面提到的示例中的任务,也可以在这里使用.还是他们都一样?

Ste*_*ary 3

您需要知道的第一件事是这async不会改变 HTTP 协议。正如我在博客中所描述的,HTTP 协议为每个请求提供一个响应。因此,您不能返回一次说它“正在进行”,然后再返回说它“已完成”。

简单的解决方案是仅在完成时返回,并使用 AJAX 在客户端抛出一些“正在进行中...”通知,在请求完成时更新页面。如果你想变得更复杂,你可以使用 SignalR 之类的东西让服务器在请求完成时通知客户端。

特别是,asyncMVC 操作不会“提前”返回;ASP.NET 将等待所有异步操作完成,然后发送响应。async服务器端的代码主要是关于可扩展性,而不是响应性。

也就是说,我通常建议在服务器端使用异步代码。一个例外是如果您只有一个数据库后端(在本博客文章中进行了很好的讨论)。如果您的后端是数据库集群或分布式/NoSQL/SQL Azure DB,那么您应该考虑将其设为异步。

如果您决定使服务器异步,只需 return Tasks; AsyncController如今只是为了向后兼容。