如何等待 Task.ContinueWith 内部任务完成
How to await until Task.ContinueWith inner task finishes
看看这段代码:
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");
}
期望的输出是:
1
2
3
4
但我得到:
1
2
4
3
这可能与 InnerTask 在不同的线程上执行有关。
我正在使用 ContinueWith,因为原始代码中的任务是通过这种方式动态创建和排队的。
使用 .Wait() 方法(见下文)有效,但我认为这是个坏主意,因为该方法是阻塞的。
task.ContinueWith(task1 => InnerTask(task1.Result).Wait())
这里正确的做法是什么?
您可以使用 TaskExtensions.Unwrap()
(这是 Task<Task>
上的扩展方法)解包外部任务并检索内部任务:
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");
}
请注意,为了简化整个事情,您可以 await
在您的任务上代替 ContinueWith
样式延续:
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");
}
看看这段代码:
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");
}
期望的输出是:
1
2
3
4
但我得到:
1
2
4
3
这可能与 InnerTask 在不同的线程上执行有关。
我正在使用 ContinueWith,因为原始代码中的任务是通过这种方式动态创建和排队的。
使用 .Wait() 方法(见下文)有效,但我认为这是个坏主意,因为该方法是阻塞的。
task.ContinueWith(task1 => InnerTask(task1.Result).Wait())
这里正确的做法是什么?
您可以使用 TaskExtensions.Unwrap()
(这是 Task<Task>
上的扩展方法)解包外部任务并检索内部任务:
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");
}
请注意,为了简化整个事情,您可以 await
在您的任务上代替 ContinueWith
样式延续:
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");
}