什么时候内联任务?

Jor*_*Day 4 .net c# multithreading task task-parallel-library

从像源在TPL内联读了之后在这里,我得到的印象是,以Task.Wait(通话)将启动尚未开始(至少使用默认的调度器)的任务.但是,写一个快速演示,如:

var taskB = new Task(
  () =>
      {
        Console.WriteLine("In TaskB");
        System.Threading.Thread.Sleep(5000);
        Console.WriteLine("Leaving TaskB");
      });

var taskA = new Task(
  () =>
      {
        Console.WriteLine("In TaskA");
        System.Threading.Thread.Sleep(500);
        Console.WriteLine("Waiting on TaskB");
        taskB.Wait();
        Console.WriteLine("Leaving TaskA");
        });

taskA.Start();
taskA.Wait();
Run Code Online (Sandbox Code Playgroud)

造成死锁.TaskA进入taskB.Wait()行,但taskB永远不会启动.我没有搞乱调度程序或任何东西,所以我不确定为什么对taskB的.Wait()调用不会导致它启动.

Jam*_*are 15

Wait()不会导致任务Start().如果你调用Wait()一个未启动的任务,它将等待它开始并完成,直到它完成,等待超时或等待被取消.由于您的呼叫Wait()不包含取消令牌或超时,因此任务完成无限.

我认为你在博客中有什么令人困惑的是这一行:

但是,如果它尚未开始执行,则Wait可能能够将目标任务从其排队的调度程序中拉出并在当前线程上内联执行.

这里的关键是短语"尚未开始执行".这并不意味着Start()没有被调用,而是Start() 调用,它调度任务并使其准备好执行,但任务尚未开始执行.

Start()有必要安排执行任务,它不会立即开始执行.这是那个模糊的主要观点.如果任务已准备好但尚未安排,则可以内联.但它不会启动甚至没有安排的任务.

如果您TaskStatus在MSDN中查看(请参阅此处),您会看到以下值:

  • 创建
  • WaitingForActivation
  • WaitingToRun
  • 运行
  • WaitingForChildrenToComplete
  • RanToCompletion
  • 取消
  • 断陷

创建任务(使用new或factory)时,它处于Created状态.在这种状态下任务没有任何变化.一旦它启动,然后它移动到WaitingForActivation等等,在此点直到它到达Running,根据该博客可能内联它是可能的.

因此,长话短说,创建任务只是将其置于Created状态,并且如果Wait()被调用则不会启动它.合理?