2016-08-20 1 views
0

Ich gründe eine Task[] Array, damit ich Task.WhenAll() wie diese verwenden:Wie kann ich Aufgabe <IEnumerable> auspacken, um mit den Ergebnissen zu arbeiten?

bei Task.WhenAll
Task[] tasks = new Task[2]; 

     tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
      "get_collaborator_nodes", portfolio, 
      recentFys, nodesSwitch); 

     tasks[1] = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
      "get_collaborator_edges", portfolio, recentFys); 

     await Task.WhenAll(); 

Der Code läuft gut und wird zu einem Schnittpunkt.

Aber jetzt gehe ich diesen Code auszuführen:

var nodes = from pi in (IEnumerable<CollaboratorNetworkNode>)tasks[0] 
        select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } }; 

und ich erhalte die Fehlermeldung:

Kann Objekt vom Typ werfen ‚System.Threading.Tasks.Task'1 [System.Collections.Generic.IEnumerable'1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]] ' Geben Sie ' System.Collections.Generic.IEnumerable'1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode] 'ein.

Wenn ich versuche, gerade dies auszuführen:

var nodes = from pi in tasks[0] 
        select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } }; 

Ich kann nicht kompilieren, weil ich die roten bekommen verschnörkelt mit:

Aufgabe enthält keine Definition für Select und die beste Erweiterung Methode Überladung "DynamicQueryable.Select (IQueryable, Zeichenfolge, Parameter Objekt [] erfordert einen Empfänger des Typs IQueryable.

Wir versuchen nur, diese beiden Retrieve-Dienste auszuführen, die jeweils 10 Sekunden dauern. Also unser Anruf ist 20 Sekunden. Ich komme jetzt in 13 bis 15 Sekunden zum Haltepunkt. Also wenn ich das zur Arbeit bringen kann, habe ich 5 bis 7 Sekunden abgeschabt.

Aber ich weiß nicht, wie man die Ergebnisse verwendet.

Wie kann ich diese Methode beenden?

+2

Sie müssen Task.Result verwenden. Wenn Sie Ihre Aufgabe als einfache 'Aufgabe' behandeln (im Gegensatz zu einer' Aufgabe '), dann müssen Sie sie zuerst umwandeln, um Zugang zu' .Result.' –

+2

'warten Task.WhenAll() ; "das wird nichts machen .... –

+0

Glorin - Kannst du ein bisschen mehr Details geben als das? – Sam

Antwort

1

Sie benötigen das Array von Aufgaben an die WhenAll Methode zu übergeben:

await Task.WhenAll(tasks); 

Dann können Sie die Ergebnisse speichern mit der Result Eigentum:

var result1 = (Task[0] as Task<IEnumerable<CollaboratorNetworkNode>>).Result; 
var result2 = (Task[1] as Task<IEnumerable<CollaboratorNetworkEdge>>).Result; 

Ändern Sie den oben, was auch immer ist die Rückkehr Art der Methoden, die Sie asynchron aufrufen.

Hinweis: Verwenden Sie Task.Result sehr sorgfältig, wenn die Task noch nicht abgeschlossen ist.

+0

Vielen Dank. Das war's. Sie haben mir gerade dabei geholfen, 6 Sekunden lang diese Methode zu rasieren. – Sam

0

Ihre Funktion _widgetDataService.RetrieveAsync hat einen Wert Rückkehr, wahrscheinlich vom Typ Aufgabe < IEnumerable < CollaboratorNetworkNode>>

Sie sollten diese Rückgabewerte in einem Array von Aufgabe gestellt, aber in einer Reihe von Aufgaben < IEnumerable < CollaboratorNetworkNode>>

var tasks = new Task<IEnumerable<CollaboratorNetWorkNode>>[][2]; 
tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
     "get_collaborator_nodes", portfolio, 
     recentFys, nodesSwitch); 

tasks[1] = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
     "get_collaborator_edges", portfolio, recentFys); 
await Task.WhenAll(tasks); 
var nodes = tasks[0].Result.Select(pi=> new GraphNode 
{ 
    Id = pi.ProfileId, 
    ... 
}) 
0

Es ist Ihre Array-Deklaration, die das Problem verursacht. Als Harald vorgeschlagen, sollte es den entsprechenden Task<T> Typ zu verwenden, anstatt die Typinformationen Verwerfen von Task mit:

var tasks = new Task<IEnumerable<CollaboratorNetworkNode>>[2]; 
tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
     "get_collaborator_nodes", portfolio, 
     recentFys, nodesSwitch); 
tasks[1] = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
     "get_collaborator_edges", portfolio, recentFys); 
var results = await Task.WhenAll(tasks); 
// results[0] is IEnumerable<CollaboratorNetworkNode> 
// results[1] is IEnumerable<CollaboratorNetworkNode> 

var nodes = from pi in results[0] 
      select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } }; 

Ich empfehle, das Ergebnis await Task.WhenAll wenn möglich (wie dieser Code der Fall ist) verwendet wird. Falls nicht möglich (d. H. Wenn die Aufgaben unterschiedliche Typen sind), sollten Sie await verwenden, um die Ergebnisse nichtResult abzurufen. Result wird alle Ausnahmen in AggregateException umbrechen, wodurch die Fehlerbehandlung erschwert wird.

Verwandte Themen