2011-07-23 17 views
7

ウェブ上でのコードの平和を見つけて、それがどのように動作するかを少し見直しましたが、今はContinueWhenALlに問題があります。完了するすべてのタスクContinueWhenすべてのタスクが完了するまで待つことはありません

List<Task> tasks = new List<Task>(); 
for (int i = 0; i < 20; i++) 
{ 
    int j = i; 
    var compute = Task.Factory.StartNew(() => results.Add(DoSomething(j))); 
    tasks.Add(compute); 
} 

私はこのコードを使用してすべてのタスクをリストに追加しています。 DoSomething機能は、私が完了し、すべてのタスクを待つためにこのコードを使用しているが、それは待たないように見える

を慰めるためBlockingCollectionから追加されたすべての結果を書き込み、別の表示機能を持っているいくつかの結果を計算し、BlockingCollectionに追加しますプログラムが開始されてからほんの数ミリ秒後に標準の "何かキーを押して続行"メッセージが表示されます。私はプログラムの最後にTask.WaitAll(consume)を追加する場合は

Task.Factory.ContinueWhenAll(tasks.ToArray(), result => results.CompleteAdding()); 

を(プログラムを完了することは〜20秒を取る必要があります)、プログラムは

var consume = Task.Factory.StartNew(() => display(results)); 
//results = BlockingCollection that I mentioned 

ファー私はそれを理解するように、プログラムが十分ではありません正常に動作しますBlockingCollectionのすべての結果を表示するにはまだ時間がありますが、すべてのタスクが完了するのを待っている間に表示するには十分な時間があります

誰かがTask.Factory.ContinueWhenAllがプログラム内にそのコード行がない(数ミリ秒後)のように計算され、プログラムは終了します。

答えて

15

Task.Factory.ContinueWhenAllはブロック方法ではありません。実際には、提供されたすべてのタスクが実行を完了したときにのみ機能する新しいタスクを開始します。したがって、プログラムが開始されてからわずか数ミリ秒後にメッセージが表示されるのが普通です。ブロック終了するタスク。 msdnから:

が提供する一連のタスクの完了時に開始される継続タスクを作成します。

どこ実行を完了するために提供タスクのすべてを待って、発信者の Task.WaitAllます ブロック

+0

「提供されたタスクのセットが完了したら」ということです。リストからすべてのタスクが完了するまで新しいタスクを作成すべきではありません。ここで唯一混乱するのは、プログラムが "その行で"待つか、プログラムが次の行に行き、すべてのタスクの完了後に新しいタスクを起動するかどうかです。 – Dan

+0

@Dan: 'ContinueWhenAll'のときプログラムは次の行に移動すると同時に、与えられたタスクが終了するまで機能しない新しいタスクを作成します。 'WaitAll' _は、その行を待っている_全ての提供されたタスクが完了するまで「ブロック」する。 –

+0

これは実際には真実ではないようですが、彼のリンクを見てくださいhttp://blogs.msdn.com/b/csharpfaq/archive/2010/06/18/parallel-programming-task-schedulers-and-synchronization-context .aspx?PageIndex = 2そして、あなたは、完了するための一連のタスクを待つContinueWhenAllメソッドをすでに使用しているということを、ある部分で見つけるでしょう。 – Dan

関連する問題