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