1

.NET4.0TPLプログラマーに質問がありました。このTPLとThreadPoolストレステスターを作成しました。Xテストを実行し、各テストはY個のタスクを実行し、終了すると次のテストに進みます。

私が抱えている問題は、1つのテストで100個のタスクを開始すると、次のテストでさらにタスクが追加されるなど、大量のスレッドが残ることです。

(私が持っているスレッド数はリソースモニターから取得されます)。

擬似コード:

while (tasksLeftToRun != 0)
{
    var nextTask = new Task(new Action(()=>
    {
        Thread.Sleep(20);
    }), cancellationToken);

    nextTask.Start();
    nextTask.ContinueWith((t) =>
    {
        //...
    },TaskScheduler.Default);
    tasksLeftToRun--;
}

アプリケーションがテストを終了してから約15秒後、スレッド数は約7に減少します。

ありがとう!

4

1 に答える 1

2

問題は、実際の作業Thread.Sleepの代わりに使用していることです。そのため、ThreadPoolは、スレッドがブロックされていることを認識し、新しいスレッドの挿入を開始します。これにより、スレッド数が時間の経過とともに増加します。

単にスリープするのではなく実際の作業を行う場合、ThreadPoolはスレッドが実際に作業を実行していることを確認し、新しいスレッドは全体的なスループットを高速化しないため、これは発生しません。

さて、この場合、あなたは継続が実際の仕事の大部分であるように見えます。その場合、最初のタスクをまったく行わない方が良いでしょう。

while (tasksLeftToRun != 0)
{
    var nextTask = new Task.Factory.StartNew(()=>
    {
        //... Actual work
    }), cancellationToken);

    tasksLeftToRun--;
}

ただし、タスクの「キュー」で作業しているように見えるため(作成するタスクが非常に多い)、Parallelクラスがこれにより適しているかどうかを調査することをお勧めします。「作品」が何らかの形でコレクションに保存されている場合は、PLINQを使用するParallel.ForEachか、PLINQを使用する方が適切な場合があります。

于 2013-03-14T15:44:06.470 に答える