2013-03-14 3 views
1

У меня возник вопрос о программистах .NET 4.0 TPL. Я создал этот тестер стресса TPL и ThreadPool, где я запускаю тесты X, каждый тест выполняет Y количество задач, когда заканчивается, он продолжает следующий тест.TPL threads count

Проблема у меня в том, что если в одном тесте запущено 100 задач, следующий тест добавит больше задач и т. Д., Оставив меня с огромным количеством потоков.

(Количество потоков, которые я взял, взято из Resource Monitor).

псевдо-код:

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

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

около 15 секунд после того, как приложение завершит с испытаниями, количество нитей падает до ~ 7.

Спасибо!

+0

Это было [задано до ответа] (http://stackoverflow.com/questions/14039051/parallel-foreach-keeps-spawning-new-threads) –

ответ

2

Проблема в том, что вы используете Thread.Sleep вместо фактической работы, поэтому ThreadPool видит, что вы заблокировали потоки и запускаете новые потоки. Это приведет к тому, что количество потоков будет расти со временем.

Если вы должны были выполнять настоящую работу, а не просто спать, этого не произошло бы, поскольку ThreadPool увидит, что потоки фактически выполняют работу, а новые потоки не ускоряют общую пропускную способность.

Теперь, в этом случае, вы продолжение, как представляется, основная часть реальной работы, в этом случае вы лучше без исходной задачи на всех:

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

    tasksLeftToRun--; 
} 

Однако, как это кажется, что вы работаете над «очередью» задач (у вас так много задач для создания), вы можете изучить, подходит ли класс Parallel для этого. Если «работа» хранится в какой-либо форме сбора, использование Parallel.ForEach или даже PLINQ может быть более уместным.

+0

Прежде всего, спасибо за быстрый ответ и ответ , теперь его работа (уменьшение количества потоков). Я не могу использовать StartNew, потому что мне нужна конфигурация задачи до фактического выполнения. О фактическом времени жизни потока - создание потоков им может занять 10 секунд и до минут. Можно ли использовать LongRunning? –

+0

@MosheDerri Что значит «мне нужна конфигурация задачи перед фактическим исполнением»? Вы можете указать это в StartNew. Что касается долгого бега - я бы не рекомендовал его, если вам это действительно не нужно. Это заставит каждую задачу использовать выделенный поток и НЕ запускаться в ThreadPool. Вы получите 1 нить/задачу (сразу), которая, скорее всего, насытит ваш процессор, если это процессор. –