2012-05-23 24 views
5

こんにちは私は_noOfThreadsを一度に実行する定義されたタスクとして持っています。だから私は%演算子を使用してタスクを続行し、ループの最後に私はTasks.WaitAllを持っています。これがコードスニペットです。Task.WaitAllは子タスクを待っていませんか?

for (int index = 0; index < count; index++) 
{ 

       if (index < _noOfThreads) 
        tasks[index] = Task.Factory.StartNew(somedelegate); 
       else 
        tasks[index % _noOfThreads].ContinueWith(task => { foo.bar(); }, 
          TaskContinuationOptions.AttachedToParent); 
} 
    Task.WaitAll(tasks); 

ただし、子タスクが完了するのを待っていないことに気付きます。親タスクが完了するとすぐに、Task.WaitAllの次の行が実行されます。子タスクを待つようにこのコードを変更するにはどうすればよいですか?私はあなたのようにあなたのタスクを割り当てていると思う

+0

[Task.Continueで期待したとおりに動作しません](http://stackoverflow.com/questions/6997480/task-continuewith-not-working-how-i-expected) – mellamokb

+0

ここでやっているように見えるのは、タスクスケジューリングを決めることです。スケジューリングをカスタマイズする場合は、[TaskScheduler](http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.aspx)から派生したものを見ることができます。つまり、デフォルトのスケジューラは、多数のタスクがキューに入れられているときに、スレッドでシステムに過負荷をかけないようにしています。 –

+0

@ダン:それは私の心配ではありません。これをTaskSchedulerに伝えたいのか分かりません。私は変数を持っており、その変数と同じくらい多くのタスクを開始したい。要するに、私は、スレッドの数を定義するセマフォのようなものをシミュレートしたいだけで、その数のスレッドだけが特定の時間にそのコードを入れることができます。 –

答えて

8

Tasks[] tasks = new Task[ _noOfThreads]; 
があるためにあなたのコードを変更し

Tasks[] tasks = new Task[count]; 

for (int index = 0; index < count; index++) 
{ 

    if (index < _noOfThreads) 
     tasks[index] = Task.Factory.StartNew(somedelegate); 
    else 
     tasks[index] = tasks[index % _noOfThreads].ContinueWith(task => { foo.bar(); }, 
          TaskContinuationOptions.AttachedToParent); 
} 
Task.WaitAll(tasks); 

はそれを試してみます!幸運:)

3

あなたは元の仕事だけを待っています。すべての継続が完了するまで待機するには、続行タスクでWaitAllに電話する必要があります。これを実現するための簡単な方法は、あなただけの最後の継続を待機しているので、元の変数に戻し、各継続タスクを再割り当てするために、次のようになります。

else 
    tasks[index % _noOfThreads] = 
     tasks[index % _noOfThreads].ContinueWith(task => { foo.bar(); }, 
         TaskContinuationOptions.AttachedToParent); 

this related questionを参照してください。

関連する問題