System.Threading.Tasks不服从开始规则?

时间:2011-09-30 00:08:37

标签: c# .net multithreading task

重写:我已经删除了问题以包含示例代码而不是链接到它以及结果和问题,因为周围的信息似乎引起了混淆。

问题:为什么任务似乎从没有开始就开始了?

这是Microsoft Website任务中的一段示例代码。它被描述为创建一个未启动的任务,创建第二个启动的任务并等待它完成,然后启动第一个任务,最后在主线程中同步启动第三个任务。

以下是示例代码的未注释版本:

using System;
using System.Threading;
using System.Threading.Tasks;

class StartNewDemo
{
    static void Main()
    {
        Action<object> action = (object obj) =>
        {
            Console.WriteLine("Task={0}, obj={1}, Thread={2}", Task.CurrentId, obj.ToString(), Thread.CurrentThread.ManagedThreadId);
        };

        Task t1 = new Task(action, "alpha");

        Task t2 = Task.Factory.StartNew(action, "beta");

        t2.Wait();

        t1.Start();

        Console.WriteLine("t1 has been launched. (Main Thread={0})", Thread.CurrentThread.ManagedThreadId);

        t1.Wait();

        Task t3 = new Task(action, "gamma");

        t3.RunSynchronously();

        t3.Wait();
    }
}

结果如下:

Task=1, obj=beta, Thread=3
t1 has been launched. (Main Thread=1)
Task=2, obj=alpha, Thread=3
Task=3, obj=gamma, Thread=1

从描述任务1(Beta)开始,只有在任务2完成后才能运行,因此主线程可以进行。这个输出似乎不是这种情况。我还运行了第二次测试运行,其中我将滴答计数显示到操作对象中并收到此信息,确认Task1确实在Task2完成之前启动。

Task=1, obj=beta, Thread=3 (634529151744201906)
t1 has been launched. (Main Thread=1)
Task=2, obj=alpha, Thread=3 (634529151744221908)
Task=3, obj=gamma, Thread=1 (634529151744221908)

我不是想在这里做任何想法,我只是在寻找一个解释,为什么在给出指令之前,Task1(obj = beta)显然正在执行。

3 个答案:

答案 0 :(得分:2)

Task=1, obj=beta, Thread=3

Task = 1在这里有点误导,因为这在示例代码中实际上是t2。你可以看到这个,因为'beta'存在。它在运行t1之前启动并完成。

t1 has been launched. (Main Thread=1)
Task=2, obj=alpha, Thread=3

这是t1(Id 2)。

Task=3, obj=gamma, Thread=1

这是t3。

答案 1 :(得分:1)

在没有某种形式的同步的情况下,不保证线程或Task到线程的分配是有序的(即非确定性的)。

答案 2 :(得分:1)

当您启动任务时,它可能不会立即执行(如果没有可用的线程池线程)。但任务永远不会自己开始。你观察到的输出是正确的。

代码执行如下:

  • t1alpha)已创建,但未执行
  • t2beta)创建,启动,打印到控制台(显然是TaskId == 1)并等待
  • t1alpha)已启动,显然是TaskId == 2
  • 打印有关启动t1的通知
  • t1alpha)打印到控制台并等待
  • 其余应该是显而易见的