2017-04-09 102 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);