为什么带有ContinueWith选项的第二个线程不等待第一个线程的结束?

时间:2015-05-09 10:16:55

标签: c# multithreading task

为什么第二个thead由行开始

var finalTask = parent.ContinueWith( .. )

是不是在等待第一个帖子的结束?这是打印输出,证明新线程没有等待第一个结束:

  

启动主螺纹1
启动ContinueWith螺纹2
0 0 0   
结束ContinueWith线程2
ContinueWith线程是   完了!
启动子螺纹3
结束子螺纹3   
启动子螺纹2
结束子螺纹2
  启动子线程1结束子线程1

代码:

public static void AttachTasksToMain()
        {
            Task<Int32[]> parent = Task.Run(() =>
            {
                Console.WriteLine("Starting main thread 1");
                var results = new Int32[3];
                new Task(() => {
                    Console.WriteLine("Starting child thread 1");
                    results[0] = 0;
                    Console.WriteLine("Ends child thread 1");
                }, TaskCreationOptions.AttachedToParent).Start();

                new Task(() => {
                    Console.WriteLine("Starting child thread 2");
                    results[1] = 1;
                    Console.WriteLine("Ends child thread 2");
                }, TaskCreationOptions.AttachedToParent).Start();

                new Task(() => {
                    Console.WriteLine("Starting child thread 3");
                    results[2] = 2;
                    Console.WriteLine("Ends child thread 3");
                }, TaskCreationOptions.AttachedToParent).Start();

                //this thread finishes when all child-thread are finished!
                return results;
            });
            //parent.Wait();

            var finalTask = parent.ContinueWith(parentTask =>
            {
                Console.WriteLine("Starting ContinueWith thread 2");
                foreach (int i in parentTask.Result)
                    Console.WriteLine(i);

                Console.WriteLine("Ending ContinueWith thread 2");
            });

            finalTask.Wait();
            Console.WriteLine("ContinueWith thread is finished!");

        }

1 个答案:

答案 0 :(得分:4)

问题是Task.Run。这将以TaskCreationOptions.DenyChildAttach开始执行任务。

使用Task.Factory.StartNew的简单更改已解决问题。那是因为默认值为TaskCreationOptions.None

See here深入讨论差异。