如何等待 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");
}