Date un'occhiata a questo codice:Come attendere fino Task.ContinueWith compito interiore finisce
private async Task InnerTask(bool outerTaskResult)
{
Console.WriteLine("2");
await Task.Factory.StartNew(() => Thread.Sleep(10000));
Console.WriteLine("3");
}
private async void Button2_Click(object sender, RoutedEventArgs e)
{
var task = Task.FromResult(false);
Task<Task> aggregatedTask = task.ContinueWith(task1 => InnerTask(task1.Result));
Console.WriteLine("1");
await aggregatedTask;
Console.WriteLine("4");
}
L'output desiderato è:
1
2
3
4
ma ottengo:
1
2
4
3
Questo probabilmente ha qualcosa a che fare con InnerTask che viene eseguito su un thread diverso.
Sto usando ContinueWith perché le attività nel codice originale vengono create dinamicamente e accodate in questo modo.
L'utilizzo del metodo .Wait() (vedere di seguito) funziona, ma penso che sia una cattiva idea, poiché il metodo sta bloccando.
task.ContinueWith(task1 => InnerTask(task1.Result).Wait())
Qual è l'approccio corretto qui?
'Unwrap' non è effettivamente necessario. Il valore di ritorno di 'await aggregatedTask' nella domanda è in realtà il compito interno. –
Ha un 'Compito', è l'attività esterna su cui è interessante, ecco perché sta completando * prima * l'esterno 'Console.WriteLine'. Può semplicemente "attendere". –
@PanagiotisKanavos Vero, non è * necessario *, si potrebbe anche "attendere" due volte. Entrambi farebbero la stessa cosa Questo è certamente un approccio appropriato. In C# 5.0 è possibile implementare 'Unwrap' come:' Public async Task Unwrap (questa attività task) {attendere l'attesa dell'attività; } '(La versione C# 4.0 è in realtà fastidiosamente lunga e noiosa.) –
Servy