2017-04-09 3 views
0

Ich habe eine Mvc Web Api und ich rufe eine lange laufende Aktion (1 Minute) mit async jquery, aber alles wird blockiert, bis das Ergebnis zurück ist.async Aufgabe blockiert Web-Anfrage

das ist meine Aktion

[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)); 

    } 

Und ich habe auch versucht, var action = await Task.Run(() => Statt await Task.Factory.StartNew

Was kann ich tun?

+0

Auf serverseitige Anforderung wird „blockiert“ werden - Antwort nur gesendet werden, wenn Sie Ihre beenden langwieriger Prozess. In ASP.NET wird 'async-wait' nur den aktuellen Thread während des" Wartens "freigeben und die Ausführung fortsetzen, wenn die Aufgabe abgeschlossen ist. Vom clientseitigen Standpunkt wird die Anfrage-Antwort synchron sein. Auf der Client-Seite können Sie Ajax verwenden, der asynchrone Aufrufe durchführt. – Fabio

+0

@Fabio i die App Reaktion auf andere Anforderung während des langen laufenden Prozess wollen, das ist, warum ich async verwendet/erwarten in erster Linie –

+2

ASP.NET Web API 2 werden Antwort auf andere Anfragen auch ohne 'async/await' – Fabio

Antwort

0

Es sieht so aus, als ob Ihre lang laufende Methode dynamisch aufgerufen wird, und Sie warten auf das Ergebnis in Ihrer asynchronen Methode, die den Thread wieder in den Thread-Pool zurückführt.

Da Sie jedoch Task.Factory.StartNew verwenden, beginnen Sie mit der Arbeit an einem neuen Thread, und führen Sie die Arbeit synchron dort, die einen Thread blockiert (das ist ein bisschen schlechter als das Aufrufen des Blockierungscodes direkt von GetParsedApplicationsAsync).

Unterm Strich ist, wenn Ihre Antwort, die Ergebnisse dieser langen Lauf Methode erfordert, sollten Sie diese Methode async machen, dann, wenn Sie es dynamisch aufrufen, warf das Ergebnis Task<T> und await das Ergebnis.

letzter Tipp, können Sie einfach das Ergebnis zurückgeben statt await Task.FromResult(...), so dass Ihre letzte Zeile sollte lauten:

return Json(action, JsonRequestBehavior.AllowGet);