2017-04-09 103 views
0

我有一个Mvc Web Api,我打电话与异步jquery长时间运行的动作(1分钟),但每件事情都将被阻止,直到结果回来。异步任务块的Web请求

这是我行动

[System.Web.Http.HttpGet] 
    public async Task<JsonResult> GetParsedApplicationsAsync(string className, string actionName) 
    { 
     var userRoles = Users.Profile.GetCurrentOrNew().Roles.Select(x => x.Id); 
     var sss = AppDomain.CurrentDomain.GetAssemblies(); 
     var assemblies = sss 
      .SelectMany(x => x.GetTypes()) 
      .Where(x => typeof(IAppSearch).IsAssignableFrom(x)); 


     var l = new List<decimal?>(); 
     foreach (var userRole in userRoles) 
     { 
      l.Add(userRole); 
     } 
     var apps = 
      new VwApplicationsDetailsDap().GetByRoleIds(l.ToArray(), Request.QueryString, "", pagenation: false); 


     // Long Running method 
     var action = await Task.Factory.StartNew(() => 
     { 
      // create instance of class 
      var type = assemblies.FirstOrDefault(x => x.Name == className); 
      var instance = Activator.CreateInstance(type, apps); 
      return type.GetMethod(actionName).Invoke(instance, BindingFlags.IgnoreCase, null, null, null); 

     }); 
     return await Task.FromResult(Json(action, JsonRequestBehavior.AllowGet)); 

    } 

而且我想也var action = await Task.Run(() => 而不是await Task.Factory.StartNew

我可以做什么?

+0

在服务器端的请求将被“封杀” - 响应将被发送,只有当你完成长期运行的过程。在ASP.NET中'async-await'只会在“等待”期间释放当前线程,并在任务完成时继续执行。从客户端角度来看,请求响应将是同步的。在客户端,您可以使用以异步方式进行调用的ajax。 – Fabio

+0

@Fabio我想在长时间运行的过程中应用程序响应其他请求,这就是为什么我首先使用了异步/等待 –

+2

即使没有“async/await”,ASP.NET Web API 2也会响应其他请求 – Fabio

回答

0

它看起来像你长时间运行的方法正在被动态调用,并且你正在等待异步方法中的结果,这将使线程返回到线程池。

但是,因为使用的是Task.Factory.StartNew,你开始一个新的线程工作,并运行工作同步有被阻塞线程(这比直接从GetParsedApplicationsAsync调用阻塞码差那么一点点)。

的底线是,如果你的反应,都需要这种长时间运行的方法的结果,你应该让这种方法async,那么当你动态地调用它,把结果以Task<T>await结果。

最后的技巧,你可以返回的结果,而不是await Task.FromResult(...),所以你的最后一行应改为:

return Json(action, JsonRequestBehavior.AllowGet);