我正在尝试连续执行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?
答案 0 :(得分:10)
您的异步lambda会提前返回new Task
认为任务已完成。它在第一个await
返回。任务构造函数是禁止的!不要使用它(几乎从不)。
它的存在基本上是框架中的设计错误。甚至不应存在未启动的任务,应删除Start
方法。我们有TaskCompletionSource
。
使用Task.Run(async () => ...
。 Task.Run
特别支持Task
返回功能。
答案 1 :(得分:2)
为了补充@ 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博客文章: