2017-02-23 38 views
0

У меня есть служба Windows, которая может получать запросы, я хочу обрабатывать в каждом запросе в отдельной ветке.ThreadPool или Task.Factory

Я хочу также ограничить количество потоков, т.е. не более 5 потоков.

И я хочу ждать для всех потоков, прежде чем я закрыть приложение,

Что такое лучший способ сделать это?

Что я пробовал:

for (int i = 0; i < 10; i++) 
     { 
      var i1 = i; 
      Task.Factory.StartNew(() => RequestHandle(i1.ToString())).ContinueWith(t => Console.WriteLine("Done")); 

     } 
     Task.WaitAll();//Not waiting actually for all threads, why? 

Таким образом, я могу ограничить число theads?

Или

var events = new ManualResetEvent[10]; 

     ThreadPool.SetMaxThreads(5, 5); 
     for (int i = 0; i < 10; i++) 
     { 
      var i1 = i; 
      ThreadPool.QueueUserWorkItem(x => 
      { 
       Test(i1.ToString()); 
       events[i1].Set(); 
      }); 
     } 

     WaitHandle.WaitAll(events); 

Существует еще один способ осуществить это?

+0

Как вы получаете запрос? Такие вопросы. Не так ясно, что вы должны использовать пул. И SetMaxThreads() - это приложение-глобальное, вы предотвращаете потоки, чтобы отменить потоки помощников. –

+0

* Как только вы набираете 'new Thread()', это закончено; ваш проект уже имеет устаревший код. * Параллельность в C# Cookbook, @StephenCleary - что также относится к 'ThreadPool' –

+0

http://stackoverflow.com/questions/9315937/net-tpl-limited-concurrency-level-task-scheduler -with-task-priority, https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.maximumconcurrencylevel, ... –

ответ

1

Task.WaitAll();//Not waiting actually for all threads, why? вы должны следующий

List<Task> tasks = new List<Task>(); 
for (int i = 0; i < 10; i++) 
     { 

      var i1 = i; 
      tasks.Add(Task.Factory.StartNew(() => RequestHandle(i1.ToString())).ContinueWith(t => Console.WriteLine("Done"))); 

     } 
    Task.WaitAll(tasks); 

Я думаю, что вы должны сделать различие между Task и ниткой

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

Тема представляет собой концепцию низкого уровня, если вы начинаете Свинец вы знаете, что это будет отдельный поток Я не думаю, что вы первый implentation достаточно хорошо, чтобы быть уверенными, что весь код выполняется, но вы должны использовать Task.Run вместо Task.Factory.StartNew

0

Оба подход должен работать, и не является гарантией что каждая операция будет работать в другом потоке (и это хорошо). Управление максимальным количеством потоков - это еще одна вещь ...

Вы можете установить максимальное количество потоков в ThreadPool с помощью SetMaxThreads. Помните, что это изменение глобально, у вас есть только один ThreadPool.

по умолчанию TaskScheduler будет использовать пул потоков (за исключением некоторых конкретных ситуаций, в которых они могут работать с Таксами рядными на тот же поток, который вызывает их), поэтому изменение параметров ThreadPool будут также влиять на Tasks.

Теперь, я сказал по умолчанию TaskScheduler. Вы можете сворачивать свои собственные, что даст вам больше контроля над тем, как будут выполняться задачи. Не рекомендуется создавать пользовательский TaskScheduler (если вам это действительно не нужно, и вы знаете, что делаете).


Для встраиваемой вопрос:

Task.WaitAll();//Not waiting actually for all threads, why?

Чтобы правильно позвонить Task.WaitAll нужно передать задачи, которые вы хотите, чтобы ждать, пока в качестве параметров.Невозможно дождаться всех существующих в настоящее время задач неявно, вам нужно сказать, какие задачи вы хотите подождать.

+0

'ThreadPool.SetMaxThreads' имеет некоторые ограничения (число связано к количеству ядер, IIS может перезаписать значения, ...) - [SmartThreadPool] (https://github.com/amibar/SmartThreadPool) может быть лучшим вариантом. –

Смежные вопросы