在我的ASP.NET MVC Web应用程序中,我正在使用有时可能需要很长时间才能响应的Web服务。在这种情况下,用户可能想要取消请求并能够发出其他请求。但是,由于服务器仍在忙于处理先前的请求,因此用户必须等到该服务器完成。出于这个原因,我决定制作一些执行密集IO作业异步的动作方法,希望主线程不被阻止。但这并没有帮助。这是我的方法:
1:public class TestController:AsyncController{
2: public async Task<ActionResult> GetString(){
3:
4: string data=await Task<string>.Factory.StartNew(()=>{
5: return service.GetDataAsString("name");
6: });
7: return View(data);
8: }
9:}
第7行不会被执行,除非服务返回预期的字符串,因此仍然阻塞。我需要做些什么才能让整个动作在一个单独的线程中进行?我必须走老时尚吗? Aren的异步方法适用于这类事情吗?
答案 0 :(得分:2)
Aren的异步方法适合这类事情吗?
不,async
不会更改HTTP协议。每个请求仍然只有一个响应,并且该响应只能发送一次。
async
将释放调用线程,但在ASP.NET上,这只意味着线程返回到线程池并能够处理其他请求;它不会向用户发送HTTP响应。在您的特定情况下,代码首先从线程池(StartNew
)获取一个线程,以便从线程池(await
)中释放一个线程,这是没有意义的。
有一些解决方案可行。你可以删除会话状态或用SignalR集线器替换这个调用(在旧的完成时允许其他用户请求),或者你可以做这个AJAX风格 - 最好是reliable queue connected to an independent worker process。