C# 本地队列中的子任务

C# 本地队列中的子任务,c#,.net,task,task-parallel-library,C#,.net,Task,Task Parallel Library,我正在读科林·坎贝尔(Colin Campbell)的一本关于并行编程的书,这时我遇到了以下几行: 从线程内调用任务工厂方法之一时 池工作线程,默认任务调度程序将新任务放置在 该线程的本地任务队列。这是一个比以前更快的操作 将其放置在全局队列中 我从上面一段中推断,我编码了以下想法,即所有任务都将由同一个工作线程执行,正如书中进一步写道的那样: 无论何时从另一个任务中或从 线程池工作项,您正在执行的操作是 一些更大的计算 但与我的预期相反,结果是: 结果: 任务的任务Id:1 B任务的任务Id:

我正在读科林·坎贝尔(Colin Campbell)的一本关于并行编程的书,这时我遇到了以下几行:

从线程内调用任务工厂方法之一时 池工作线程,默认任务调度程序将新任务放置在 该线程的本地任务队列。这是一个比以前更快的操作 将其放置在全局队列中

我从上面一段中推断,我编码了以下想法,即所有任务都将由同一个工作线程执行,正如书中进一步写道的那样:

无论何时从另一个任务中或从 线程池工作项,您正在执行的操作是 一些更大的计算

但与我的预期相反,结果是:

结果:

任务的任务Id:1
B任务的任务Id:2
D任务的任务Id:4
C任务的任务Id:3

期望值:

任务的任务Id:1
B任务的任务Id:1
D任务的任务Id:1
C任务的任务Id:1


好像我的直觉误导了我!我在哪里失去了线索?

你忘了偷工作,它可能与你的第一个报价在同一部分。如果你去掉睡眠和等待,你会得到什么结果。还有任务Id!=线程Id您正在检查错误的值以查看线程共享。

您忘记了工作窃取,它可能与您的第一个报价位于同一部分。如果你去掉睡眠和等待,你会得到什么结果。还有任务Id!=线程Id您正在检查错误的值以查看线程共享。
       Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("Task Id for A task: {0}", Thread.CurrentThread.ManagedThreadId);

             // subtasks within Global Task 
            var t2 = Task.Factory.StartNew(() => { Thread.Sleep(500); Console.WriteLine("Task Id for B task : {0}", Thread.CurrentThread.ManagedThreadId); });  
            var t3 = Task.Factory.StartNew(() => { Thread.Sleep(1000); Console.WriteLine("Task Id for C task: {0}", Thread.CurrentThread.ManagedThreadId); });  
            var t4 = Task.Factory.StartNew(() => { Thread.Sleep(2000); Console.WriteLine("Task Id for D task: {0}", Thread.CurrentThread.ManagedThreadId); });  

            Task.WaitAll(t2, t3, t4);
        });