等待调用异步方法的任务完成而不阻塞线程

wait for a Task that calls an async method to complete without blocking thread

我正在尝试连续执行 2 个任务,但是第二个任务是 运行 在第一个任务完全完成之前,因为它是可等待的

var task1 = new Task(async () =>
{
    Trace.WriteLine("before delay");
    await Task.Delay(1000);
    Trace.WriteLine("after delay");
});

task1.ContinueWith(task => Trace.WriteLine("continued"));

task1.Start();
task1.Wait();

我想引出输出

before delay 
after delay 
continued

但我明白了

before delay
continued

有没有办法在不阻塞线程的情况下阻塞 task1?

你的异步 lambda returns 提前让 new Task 认为任务已经完成。它 returns 在第一个 await。任务构造函数是禁区!不要使用它(几乎从不)。

它的存在基本上是框架的设计错误。甚至不应该存在未启动的任务,并且应该删除 Start 方法。为此,我们有 TaskCompletionSource

使用Task.Run(async () => ...Task.RunTask 返回函数有特殊支持。

为了补充@usr 的回答,我认为值得展示如何通过这些小的更改使现有代码正常工作:

Task<Task> task1 = new Task<Task>(new Func<Task>(async () =>
{
    Trace.WriteLine("before delay");
    await Task.Delay(1000);
    Trace.WriteLine("after delay");
}));

var task2 = task1.Unwrap();

var task3 = task2.ContinueWith(task => Trace.WriteLine("continued"));

task1.Start();
task3.Wait();

希望这有助于更好地理解实际任务工作流程。 Task.Unwrap如果使用得当,可以成为一个强大的工具。

也就是说,您确实不需要通过其构造函数创建 Task 对象。要了解更多信息,请查看 TPL 的 Stephen Toub 博客文章: