TaskCreationOptions.AttachedToParent不授予专利Task等待子级

时间:2019-01-24 21:06:23

标签: c#

根据书籍Kort W. - Exam Ref 70-483. Programming in C#,父线程应始终等待子线程并带来结果:

0 1 2

但是在大​​多数情况下,我有

0 0 0

我期望TaskCreationOptions.AttachedToParent将使主线程等待子线程。

public static void parenThr()
{

    Task<Int32[]> parent = Task.Run
    (
        () =>
        {
            var results = new Int32[3];

            new Task(() => results[0] = 0, TaskCreationOptions.AttachedToParent).Start();
            new Task(() => results[1] = 1, TaskCreationOptions.AttachedToParent).Start();
            new Task(() => results[2] = 2, TaskCreationOptions.AttachedToParent).Start();

            return results;
        }
    );

    parent.ContinueWith(
        (s) =>
        {
            foreach (var i in s.Result)
            {
                Console.WriteLine("res {0}",i);
            }
        }
    );

}

为什么主线程不等待子进程完成?

1 个答案:

答案 0 :(得分:0)

默认情况下,Task.Run$selectedImageId = 2; $images = \App\Models\Image::orderByRaw('case when id=? then -1 else 0 end, created_at desc', [$selectedImageId])->get(); 开头。

来自MSDN

  

TaskCreationOptions.DenyChildAttached

     

指定任何试图作为附件执行的子任务   子任务(即,它是使用AttachedToParent选项创建的)   将无法附加到父任务,而是执行   作为一个独立的子任务。有关更多信息,请参见附件和   分离的子任务。

您应该使用TaskCreationOptions.DenyChildAttached,以便您可以指定自己的参数。

Task.Factory.StartNew

为避免与public static async Task Do() { Task<int[]> parent = Task.Factory.StartNew ( () => { var results = new int[3]; Task.Factory.StartNew(() => results[0] = 0, default(CancellationToken), TaskCreationOptions.AttachedToParent, TaskScheduler.Default); Task.Factory.StartNew(() => results[1] = 1, default(CancellationToken), TaskCreationOptions.AttachedToParent, TaskScheduler.Default); Task.Factory.StartNew(() => results[2] = 2, default(CancellationToken), TaskCreationOptions.AttachedToParent, TaskScheduler.Default); return results; } , default(CancellationToken), TaskCreationOptions.None, TaskScheduler.Default); var ints = await parent; foreach (var i in ints) { Console.WriteLine("res {0}", i); } } 一起使用时可能造成的混淆,您应该对TaskScheduler参数使用重载。