操作完成前MVC4 + async / await +返回响应
在我的MVC4应用程序中,我需要添加一个控制器来上传和处理大文件。 文件上传后,我需要立即启动该文件的异步处理并将响应返回给浏览器,而无需等待处理完成。
显然我可以手动启动一个新线程来处理文件,但是我想知道我是否可以使用.net 4.5引入的async / await机制来实现这个场景
为了测试这个概念,我尝试过这样的事情:
public async Task Test() { TestAsync(); return View("Test"); } public async void TestAsync() { await LongRunning(); } private Task LongRunning() { return Task.Factory.StartNew(() => Pause()); } private int Pause() { Thread.Sleep(10000); return 3; }
异步机制似乎一般工作:当我调试代码时,我点击“返回视图(”测试“);” 行“返回3”之前的行。 但是,浏览器仅在Pause方法完成后才会收到响应。
这看起来像常规异步控制器(具有Async和Completed方法的控制器)。 有没有办法在控制器中为我的场景使用async / await?
显然我可以手动启动一个新线程来处理文件,但是我想知道我是否可以使用.net 4.5引入的async / await机制来实现这个场景
不,你不能,因为async
不会改变HTTP协议 。
Svick和James已经发布了正确的答案作为评论,为方便起见我在下面重复:
IIS可以随时回收您的应用程序。
如果您有长时间运行的事情要求异步,请在其他地方执行。 “典型”是一个持久性队列(MSMQ,Azure,RabbitMQ等),其他东西(Windows服务,由任务调度程序运行的exe,使用Quartz.net的应用程序等)处理它们。
总而言之,HTTP为您提供了一个请求和一个响应( async
– 以及其他任何内容 – 不会改变这一点)。
ASP.NET是围绕HTTP请求设计的(并假设“如果没有未完成的请求,则可以安全地停止此网站”)。 您可以启动一个新线程并将您的上传保存在内存中(这是最简单的方法),但强烈建议不要这样做。
根据您的情况,我建议您遵循詹姆斯的建议:
这有一些变化(例如,使用SignalR在处理完成时通知浏览器),但一般架构是相同的。
这很复杂,但这是正确的方法。
您的代码中有错误。 您必须等待操作中对TestAsync的调用。 如果不这样做,它只返回一个“任务”对象而不运行任何东西。
public async Task Test() { await TestAsync(); return View("Test"); }
并且在异步方法中睡眠的正确方法是调用
await Task.Delay(10000);
您必须更改TestAsync的签名:如果返回void,则不应将方法标记为异步。 它必须返回Task。 保留返回void以与.net事件兼容。
public async Task TestAsync() { await LongRunning(); }
方法体是相同的。
你的LongRunning方法同步睡眠10秒。 改变它,以便在任务中发生睡眠。
上述就是C#学习教程:操作完成前MVC4 + async / await +返回响应分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1040978.html