Jetez un oeil à ce code:
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 aggregatedTask = task.ContinueWith(task1 => InnerTask(task1.Result)); Console.WriteLine("1"); await aggregatedTask; Console.WriteLine("4"); }
La sortie souhaitée est:
1 2 3 4
Mais je reçois:
1 2 4 3
Cela a probablement quelque chose à voir avec l’exécution d’InnerTask sur un autre thread.
J’utilise ContinueWith car les tâches du code d’origine sont créées et mises en queue de manière dynamic.
Utiliser la méthode .Wait () (voir ci-dessous) fonctionne, mais je pense que c’est une mauvaise idée, car la méthode bloque.
task.ContinueWith(task1 => InnerTask(task1.Result).Wait())
Quelle est la bonne approche ici?
Vous pouvez utiliser TaskExtensions.Unwrap()
(qui est une méthode d’extension sur Task
) pour décompresser la tâche de sortie et récupérer la tâche interne:
private async void Button2_Click(object sender, RoutedEventArgs e) { var task = Task.FromResult(false); Task aggregatedTask = task.ContinueWith(task1 => InnerTask(task1.Result)).Unwrap(); Console.WriteLine("1"); await aggregatedTask; Console.WriteLine("4"); }
Notez que pour simplifier tout cela, au lieu de ContinueWith
style continuation, vous pouvez await
pour vos tâches:
private async void Button2_Click(object sender, RoutedEventArgs e) { var task = Task.FromResult(false); Console.WriteLine("1"); var result = await task; await InnerTask(result); Console.WriteLine("4"); }