根据书籍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);
}
}
);
}
为什么主线程不等待子进程完成?
答案 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参数使用重载。