2016-09-14 3 views
2

Ich muss Elemente aus Partitionen in Service Fabric zurückgeben und sie zu einer Liste hinzufügen. Die Ergebnisse stammen von asynchronen Methoden. Ich versuche zu verstehen, was passiert, damit es schneller läuft. Wartet die Schleife, bis für jedes GetItems-Element eine Wartezeit zurückgegeben wird, oder wird die Schleife fortgesetzt und ein neues GetItems für die nächste Partition gestartet?Hinzufügen von Elementen zu einer Liste aus der asynchronen Methode

List<string> mylist = new List<string>(); 

foreach(var partition in partitions) 
{ 
    var int64RangePartitionInformation = p.PartitionInformation as Int64RangePartitionInformation; 
    if (int64RangePartitionInformation == null) continue; 
    var minKey = int64RangePartitionInformation.LowKey; 
    var assetclient = ServiceProxy.Create<IService>(serviceName, new ServicePartitionKey(minKey)); 
    var assets = await assetclient.GetItems(CancellationToken.None); 
    mylist.AddRange(items) 
} 

Antwort

3

Das await Schlüsselwort teilt den Compiler Ihre Methode zu einer Zustandsmaschine Refactoring. Sobald Ihre async Methode aufgerufen wird, wird alles vor der ersten await ausgeführt. Der Rest der Tasks wird für eine verzögerte Ausführung registriert und kann abhängig von der aktuellen Konfiguration sofort und synchron oder auf einem anderen Thread ausgeführt werden.

Wenn die erwartete Aufgabe asynchron ausgeführt wird, kehrt der eigentliche Methodenaufruf zurück, so dass der Thread frei ist, etwas anderes zu tun, z. Aktualisieren Sie die Benutzeroberfläche. Diese refaktorierte zustandsmaschinenartige Methode wird dann immer wieder aufgerufen, fragt ab, ob die erwartete Aufgabe beendet ist. Sobald es fertig ist, wird der Zustand umgeschaltet, so dass die Codes nach der erwarteten Zeile ausgeführt werden und so weiter.

Also logisch ja, die Schleife wartet, bis die Ergebnisse da sind, aber in Wirklichkeit ist der Thread wegen des oben erwähnten zustandsmaschinenartigen Verhaltens nicht blockiert.

Siehe eine detaillierte Erklärung here.

Update:

Wenn die Ergebnisse können parallel von allen Partitionen erhalten werden, sie erwarten nicht, sie eins nach dem anderen. Verwenden Sie stattdessen Parallel.ForEach oder einfach nur eine Task Sammlung in Ihrer foreach Schleife bevölkert, und sie schließlich in einem Schritt erwarten:

await Task.WhenAll(myTasks); 
3

await ist eine „asynchrone wait“. Es pausiert die aktuelle Methode und wartet (asynchron), bis diese Operation abgeschlossen ist, bevor sie fortgesetzt wird.

Beachten Sie, dass die Methode pausiert ist, nicht die Thread. Das macht await eine "asynchrone Wartezeit" anstelle einer regulären Wartezeit ("synchrone Wartezeit").

Für weitere Informationen, siehe meine async/await intro.

Ist die Schleife warten, bis await wird für jedes GetItems zurückgegeben, oder hat die Schleife fortgesetzt und eine neue GetItems für die nächste Partition starten?

Bei jedem await wartet die Schleife (asynchron). Mit dem aktuellen Code wird also nur ein Aufruf an den Dienst gleichzeitig ausgeführt, und die Liste muss nicht gleichzeitig mit AddRange Aufrufen arbeiten.

Verwandte Themen