Führen Sie eine Reihe von Aufgaben nacheinander aus
Der einfache Weg (mit Microsoft.Bcl.Async
):
static async Task<TState> AggregateAsync<T, TState>(
this IEnumerable<T> items,
TState initial,
Func<TState, T, Task<TState>> makeTask)
{
var state = initial;
foreach (var item in items)
state = await makeTask(state, item);
return state;
}
Auf die harte Tour:
static Task<TState> AggregateAsync<T, TState>(
this IEnumerable<T> items,
TState initial,
Func<TState, T, Task<TState>> makeTask)
{
var tcs = new TaskCompletionSource<TState>();
tcs.SetResult(initial);
Task<TState> ret = tcs.Task;
foreach (var item in items)
{
var localItem = item;
ret = ret.ContinueWith(t => makeTask(t.Result, localItem)).Unwrap();
}
return ret;
}
Beachten Sie, dass die Fehlerbehandlung auf dem "harten" Weg umständlicher ist; eine Ausnahme vom ersten Element wird in AggregateException
eingeschlossen durch jeden aufeinanderfolgenden Artikel. Der "einfache" Weg schließt solche Ausnahmen nicht ein.
Sie können Task.ContinueWith
verwenden . Die task
Sie sehen im Code unten, stellt die vorherige (abgeschlossene) Aufgabe dar, und Sie können ihr Ergebnis abrufen, um die zweite Aufgabe auszuführen, und so weiter.
T item1 = default(T);
T item2 = default(T);
Task<TState> task1 = makeTask(initial, item1);
//create second task
task1.ContinueWith(task => makeTask(task.Result, item2).Result,
TaskContinuationOptions.OnlyOnRanToCompletion);
Bearbeiten
Tut mir leid, ich habe diesen Teil verpasst
Dazu müssen Sie lediglich eine Referenz auf das Ergebnis der letzten ContinueWith
zurückgeben anrufen.
Task<State> aggregate = task1.ContinueWith(
task => makeTask(task.Result, item2).Result,
TaskContinuationOptions.OnlyOnRanToCompletion);
var res = aggregate .Result; //wait synchronously for the result of the sequence