2

アダム・フリーマン著「C#でのPro .NET 4並列プログラミング」という本を読んでいます。第2章13ページでは、task1.Resultを使用して結果を返すためにTask<int>を使用して終了するまで待機する方法について説明します。 task2task1が完了するのを待たなければならない理由は分かりません。彼らは別のスレッドにあります。C#.net 4パラレルプログラミング

それは以下のようなものです:私はtask1のように、まだ最初、私が試した回数に関係なく実行思わ一番下に行を次のように移動した場合

Task<int> task1 = new Task<int>(() => { ... ; return sum }); 
task1.Start(); 
Console.WriteLine("Result 1: {0}", task1.Result); 

Task<int> task2 = new Task<int>(() => { ... ; return sum }); 
task2.Start(); 
Console.WriteLine("Result 2: {0}", task2.Result); 

Console.WriteLine("Result 1: {0}", task1.Result); 

どうしてですか?

答えて

0

最初に実際に終了するタスク、つまりreturn文に最初に当たるタスクは、正式には予測できません。結果を受け入れる前に仕事を終えることができます。

サンプルタスクの仕事がそれほど大きくない場合、最初にResultを受け入れなくてもtask1が最初に終了することになります(またはJavaスレッドの用語集で参加しても)。それはあなたが最初に始めたからです。

おそらくあなたは何とかtask1が最初に終了したことを知っています。あなたのタスクのコードにConsole.WriteLineが埋め込まれていますか?その場合は、コンソールサブシステムが操作をシリアル化するので、最初に使用するタスクが完全に実行されてから、2番目のタスクが開始されることに注意してください。あなたの2つのタスクはコンソールに競争し、勝者はすべてを取る。

task1は、メインスレッドが第2のnewでtask2を構築する前にオフで実行されているため、このレースで不公平な利点があります。

+0

あなたの答えをありがとう – Fei

3

Task.Resultブロックは、Taskが完了するまでブロックされます。

戻るには結果が必要です。

したがって、最初の例ではtask1が完了するまでtask2は開始されません。

task1.Resultを下に移動すると、どのタスクが最初に完了するかは不定ですが、Console.WriteLineステートメントは順番に実行されます。

+0

ニコラス、返信ありがとうございます。私は仕事を理解することができます。仕事は仕事が終了するまで待つでしょう。task1が既に起動している場合、実行する別のタスク(スレッド)を開始できませんか?次のような別の例があります:foreach(メッセージの文字列msg){タスクtsk =新しいタスク(obj => printMsg(obj)、msg); tsk.Start();} foreachループ内のタスクは並列に実行されます。 – Fei

0

task.Wait()メソッドを使用してください。

 Task<int> task1 = new Task<int>(() => { int sum = 0; return sum; }); 
     task1.Start(); 
     task1.Wait(); 
     Console.WriteLine("Result 1: {0}", task1.Result); 

     Task<int> task2 = new Task<int>(() => { int sum = Enumerable.Range(1, 10).Sum(); return sum; }); 
     task2.Start(); 
     task1.Wait(); 
     Console.WriteLine("Result 2: {0}", task2.Result); 
+0

同じ結果が得られるはずですが、明示的に「待機」しているので読みやすくなります。 – Bengie

+0

あなたの答えをありがとう。 – Fei

0

"Console.WriteLine("結果1:{0} "、task1.Result);" task1が終了するまで実行できないため、待機します。

タスクは互いに独立して実行されますが、呼び出しスレッドはconsole.writelineを順番に呼び出します。これらの2つのタスクの結果は、順不同であることが強制されます。

0

Task task1 = new Task(() => { ... ; return sum });
task1.Start();
Task task2 = new Task(() => { ... ; return sum });
task2.Start();
task1.Wait()
Console.WriteLine("Result 1: {0}", task1.Result);
task2.Wait()
Console.WriteLine("Result 2: {0}", task2.Result);

これを試してみてください。ここでは、console.writelineを呼び出す前に両方のタスクを開始する必要があります。

関連する問題