C# 等待调用异步方法的任务在不阻塞线程的情况下完成

C# 等待调用异步方法的任务在不阻塞线程的情况下完成,c#,async-await,task-parallel-library,task,C#,Async Await,Task Parallel Library,Task,我试图连续执行两个任务,但第二个任务在第一个任务完全完成之前运行,因为它是可以等待的 var task1 = new Task(async () => { Trace.WriteLine("before delay"); await Task.Delay(1000); Trace.WriteLine("after delay"); }); task1.ContinueWith(task => Trace.WriteLine("continued")); t

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

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会提前返回,从而使
新任务
认为任务已完成。它在第一次
等待时返回。任务构造函数是禁止进入的!不要使用它(几乎从不)

它的存在基本上是框架中的一个设计缺陷。甚至不应该存在未启动的任务,并且应该删除
Start
方法。为此,我们提供了
TaskCompletionSource


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

为了补充@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 task1=新任务(新函数(异步()=>
{
Trace.WriteLine(“延迟前”);
等待任务。延迟(1000);
Trace.WriteLine(“延迟后”);
}));
var task2=task1.Unwrap();
var task3=task2.ContinueWith(task=>Trace.WriteLine(“continued”);
task1.Start();
任务3.等待();
希望这有助于更好地理解实际的任务工作流。如果使用得当,可以成为一个有力的工具

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


他还需要分配任务1的结果。继续(…)
转到另一个任务,然后等待该任务,而不是
任务1
。太好了!我在哪里可以获得更多关于这方面的内部工作和最佳实践的详细信息?不幸的是,我不知道有任何这样的地方。应该有一个网站详细介绍TPL最常见的10个问题。实际上,95%的堆栈溢出问题来自10个问题。@ArghyaC,检查并标记Wiki。它们有太多有用的链接。此外,我通常不会推荐非免费资源,但会得到一份。@ArghyaC:我一直在做一项工作,试图指出哪些API用于哪些目的(哪些应该完全避免)。