Wie Sie bei der Ausführung von Task.WhenAny einen Retourenartikel abgeben

Ich habe zwei Projekte in meiner Lösung: WPF-Projekt und Klassenbibliothek.

In meiner Klassenbibliothek:

Ich habe eine Liste mit Symbolen:

class Symbol
{
     Identifier Identifier {get;set;}
     List<Quote> HistoricalQuotes {get;set;}
     List<Financial> HistoricalFinancials {get;set;}
}

Für jedes Symbol frage ich einen Finanzdienst ab, um mithilfe einer Webanforderung historische Finanzdaten für jedes meiner Symbole abzurufen. (webClient.DownloadStringTaskAsync (uri);)

Also hier ist meine Methode, die das macht:

    public async Task<IEnumerable<Symbol>> GetSymbolsAsync()
    {
        var historicalFinancialTask = new List<Task<HistoricalFinancialResult>>();

        foreach (var symbol in await _listSymbols)
        {
            historicalFinancialTask.Add(GetFinancialsQueryAsync(symbol));
        }

        while (historicalFinancialTask.Count > 0)
        {
            var historicalFinancial = await Task.WhenAny(historicalFinancialTask);
            historicalFinancialTask.Remove(historicalFinancial);

            // the line below doesn't compile, which is understandable because method's return type is a Task of something
            yield return new Symbol(historicalFinancial.Result.Symbol.Identifier, historicalFinancial.Result.Symbol.HistoricalQuotes, historicalFinancial.Result.Data); 
        }
    }

    private async Task<HistoricalFinancialResult> GetFinancialsQueryAsync(Symbol symbol)
    {
        var result = new HistoricalFinancialResult();
        result.Symbol = symbol;
        result.Data = await _financialsQuery.GetFinancialsQuery(symbol.Identifier); // contains some logic like parsing and use WebClient to query asynchronously
        return result;
    }

    private class HistoricalFinancialResult
    {
        public Symbol Symbol { get; set; }
        public IEnumerable<Financial> Data { get; set; }

        // equality members
    }

Wie Sie sehen, möchte ich, dass jedes Mal, wenn ich historische Finanzdaten pro Symbol herunterlade, das Ergebnis angezeigt wird, anstatt darauf zu warten, dass alle meine Aufrufe an den Finanzdienstleister abgeschlossen sind.

Und in meinem WPF möchte ich Folgendes tun:

foreach(var symbol in await _service.GetSymbolsAsync())
{
      SymbolsObservableCollection.Add(symbol);
}

Anscheinend können wir mit einer asynchronen Methode keine Rendite erzielen. Welche Lösung kann ich dann verwenden? Mit Ausnahme des Verschiebens meiner GetSymbols-Methode in mein WPF-Projekt.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage