asyncAction方法应该使用await吗?我需要在我的控制器中为长时间运行的外部API调用实现异步操作。查看一些教程,我已经实现了我的方法:[AsyncTimeout(200)]publicasyncTaskDoAsync(){//执行长时间运行的调用。返回视图();我的问题是,这是否足以使真正的非阻塞异步?我还需要应用await运算符吗?如果需要,我该怎么做?我需要在我的控制器中为长时间运行的外部API调用实现异步操作。...我的问题是,这足以实现真正的非阻塞异步吗?我还需要应用await运算符吗?如果需要,我该怎么做?C#编译器可能建议此处的async关键字是多余的:[AsyncTimeout(200)]publicasyncTaskDoAsync(){//执行长时间运行的调用。返回视图();您添加async关键字的事实并不能使您的方法神奇地在后台运行。如果您按照另一个答案的建议执行类似awaitTask.Run(()=>View())的操作,您仍然不会打破给定HTTP请求的边界。请求处理将至少花费与不使用Task.Run生成视图相同的时间。客户端浏览器仍将等待它。当您需要将受CPU限制的工作卸载到池线程时,此模式适用于UI应用程序,以避免阻塞UI线程并保持UI响应。但是,在ASP.NET应用程序内的HTTP请求处理程序中使用它并不是一个好主意。它只会损害性能和可扩展性。一种解决方案,可提供用户友好的体验,以在视图花费大量时间编写时运行跨越单个HTTP请求边界的后台任务。然后它更进一步使用AJAX请求来保持客户端浏览器的进度更新。这是AlanD.Jackson的一个很好的例子,就是这样:Asp.NetMVC3中的长时间运行的后台任务。但是,在同一个ASP.NET服务器进程中跨多个HTTP请求运行冗长的后台操作并不是一个好主意。虽然实现起来相对容易,但这种方法可能会在IIS的可维护性、可伸缩性和安全性方面产生问题。您可能最好使用单独的Windows/WCF服务,它公开基于任务的API。然后使用AJAX定期轮询WCF服务,使用ASP.NETMVC控制器的专用方法作为轮询调用的代理。要编写非阻塞异步代码,您需要执行某种现有的非阻塞异步操作,例如Task.Delay()或异步网络或文件IO。简而言之,await关键字消耗async;它不会创建它。如果您没有任何实际的异步工作要做,那么await对您没有任何好处。正如另一个人所写,您需要一个异步操作来等待它,使View()异步将其包装在Task.Run[AsyncTimeout(200)]publicasyncTaskDoAsync(){//执行长时间运行的call.returnawaitTask.Run(()=>查看());},此方法主要用于从其他异步函数或回调中调用。我的问题是,这足以实现真正的非阻塞异步吗?我还需要应用await运算符吗?如果需要,我该怎么做?出于以下原因,您应该将await关键字与异步MVC操作一起使用:如果您的操作更改了应用程序的状态(更新数据库等),则await关键字允许您在外部服务失败时回滚更改。否则这可能会导致状态不一致,因为用户不能只重放给定的异步操作,它只能重放整个操作。托管环境(IIS)可能会因不同原因导致应用程序域卸载。当它发生时,您的应用程序永远无法获得异步操作的结果。在正常请求处理的情况下,ASP.NET等待每个操作完成。如果某些请求需要很长时间才能完成(并超过关闭超时),ASP.NET将中止它们并发送失败响应。这就是为什么您既不应该使用异步也不应该使用TPL等其他.NET异步技术的原因。在这种情况下,使用WCF的自定义Windows服务是更好的解决方案,但它会使编程、部署和维护任务变得相当复杂。当然,你可以使用HostingEnvironment.RegisterObject,这里有一篇很好的文章。但是当ASP.NET调用IRegisteredObject接口实现的Stop方法时(在关闭期间),您只有30秒(默认情况下)来保存数据。如果您有未完成的异步操作,您应该中止它们,将它们标记为失败并在重启后重试或向用户发送失败通知。如果您的存储空间目前也不可用,请告知我们您的结果(包括失败的)。您还可以在ASP.NET应用程序中使用持久队列、可靠提取和侦听这些队列的专用工作器。即使工作进程终止,这也会保护您。此外,还有许多项目,如Resque、Sidekiq、Pyres等,但它们是针对其他语言的。对于.NET,试试HangFire——这是一项正在进行的工作,但比这些系统的初始实现更稳定,并且具有许多不同的功能。以上是C#学习教程:await异步Action方法要不要用?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
