AttachedToParent
のパラメータの仕組みを理解することに問題があります。私が理解したようAttachedToParentタスクの混乱
public static void Main(string[] args)
{
Task<int[]> parentTask = Task.Run(()=>
{
int[] results = new int[3];
Task t1 = new Task(() => { Thread.Sleep(3000); results[0] = 0; }, TaskCreationOptions.AttachedToParent);
Task t2 = new Task(() => { Thread.Sleep(3000); results[1] = 1; }, TaskCreationOptions.AttachedToParent);
Task t3 = new Task(() => { Thread.Sleep(3000); results[2] = 2; }, TaskCreationOptions.AttachedToParent);
t1.Start();
t2.Start();
t3.Start();
return results;
});
Task finalTask = parentTask.ContinueWith(parent =>
{
foreach (int result in parent.Result)
{
Console.WriteLine(result);
}
});
finalTask.Wait();
Console.ReadLine();
}
、タスクが子タスクを持っている場合、すべての子タスクが準備ができているとき、親はタスクの終了:ここ
は、サンプルコードです。この例の問題は、出力が次のようになっていることです。0
0
0
これは、親タスクが子タスクの完了を待っていないことを意味します。有効な結果0 1 2
を取得する唯一の方法は、return results;
文の前にこのようなコードのいくつかの作品を追加することによって、子供Taksのすべてに待って使用することです:
Task[] taskList = { t1, t2, t3 };
Task.WaitAll(taskList);
私の質問はこれです。すべての子タスクに対して手動でWaitメソッドを呼び出さなければならないときは、なぜTaskCreationOptions.AttachedToParent
を使用するのですか?
編集:私はこの質問を書いていたが
、私は、コードを少し変更しましたし、今AttachedToParentはうまく動作します。唯一の違いはTask.Run();
の代わりにparentTask.Start();
を使用したことです。
public static void Main(string[] args)
{
Task<int[]> parentTask = new Task<int[]>(()=>
{
int[] results = new int[3];
Task t1 = new Task(() => { Thread.Sleep(3000); results[0] = 0; }, TaskCreationOptions.AttachedToParent);
Task t2 = new Task(() => { Thread.Sleep(3000); results[1] = 1; }, TaskCreationOptions.AttachedToParent);
Task t3 = new Task(() => { Thread.Sleep(3000); results[2] = 2; }, TaskCreationOptions.AttachedToParent);
t1.Start();
t2.Start();
t3.Start();
//Task[] taskList = { t1, t2, t3 };
//Task.WaitAll(taskList);
return results;
});
parentTask.Start();
Task finalTask = parentTask.ContinueWith(parent =>
{
foreach (int result in parent.Result)
{
Console.WriteLine(result);
}
});
finalTask.Wait();
Console.ReadLine();
}
最初の例に問題がある理由はまだ分かりません。このブログ記事で
* DenyChildAttach *が本当に問題であるようです。このような親タスクを作成すると、 'TaskFactory tf = new TaskFactory(TaskCreationOptions.DenyChildAttach、TaskContinuationOptions.None); タスク parentTask = tf.StartNew(()=> {....}); '同じ問題が発生し、* TaskCreationOptions.None *を使用するとうまく動作します。 –