Максимальное количество элементов в очереди в ThreadPool.QueueUserWorkItem - PullRequest
8 голосов
/ 19 января 2010

Я установил максимальный поток равным 10. Затем я добавил задачу 22000, используя ThreadPool.QueueUserWorkItem. Весьма вероятно, что не все задачи 22000 были выполнены после запуска программы. Есть ли ограничение, сколько задач может быть поставлено в очередь для доступных потоков?

Ответы [ 4 ]

12 голосов
/ 19 января 2010

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

Это относительно чистый способ справиться с ситуацией такого типа:

 using (var mre = new ManualResetEvent(false))
 {
      int remainingToProcess = workItems.Count(); // Assuming workItems is a collection of "tasks"
      foreach(var item in workItems)
      {
           // Delegate closure (in C# 4 and earlier) below will 
           // capture a reference to 'item', resulting in
           // the incorrect item sent to ProcessTask each iteration.  Use a local copy
           // of the 'item' variable instead.
           // C# 5/VS2012 will not require the local here.
           var localItem = item;
           ThreadPool.QueueUserWorkItem(delegate
           {
               // Replace this with your "work"
               ProcessTask(localItem);

               // This will (safely) decrement the remaining count, and allow the main thread to continue when we're done
               if (Interlocked.Decrement(ref remainingToProcess) == 0)
                      mre.Set();
           });
      }
      mre.WaitOne();
 }

При этом, как правило, лучше "группировать" вместе ваши рабочие элементы, если у вас их тысячи, а не рассматривать их как отдельные рабочие элементы для пула потоков. Это некоторые накладные расходы, связанные с управлением списком элементов, и, поскольку вы не сможете обрабатывать 22000 одновременно, лучше сгруппировать их в блоки. Имея по одному рабочему элементу каждый процесс 50 или около того, вероятно, немного увеличит вашу общую производительность ...

6 голосов
/ 19 января 2010

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

4 голосов
/ 19 января 2010

Это вопрос, зависящий от реализации, и реализация этой функции со временем немного изменилась.Но в .Net 4.0 вы существенно ограничены объемом памяти в системе, поскольку задачи хранятся в очереди в памяти.Это можно увидеть, просмотрев реализацию в отражателе.

4 голосов
/ 19 января 2010

Из документации ThreadPool :

Примечание: Потоки в управляемом пуле потоков являются фоновыми потоками. То есть их свойства IsBackground верны. Это означает, что поток ThreadPool не будет поддерживать работоспособность приложения после выхода из всех потоков переднего плана.

Возможно ли, что вы выходите до того, как все задачи будут обработаны?

...