Ограничение количества потоков пула - PullRequest
3 голосов
/ 16 мая 2011

Я использую ThreadPool в моем приложении.Сначала я установил предел пула потоков с помощью следующего:

ThreadPool.SetMaxThreads(m_iThreadPoolLimit,m_iThreadPoolLimit);
m_Events = new ManualResetEvent(false);

, а затем поставил в очередь задания, используя следующее

WaitCallback objWcb = new WaitCallback(abc);
ThreadPool.QueueUserWorkItem(objWcb, m_objThreadData); 

Здесь abc - это имяфункция, которую я вызываю.После этого я делаю следующее, чтобы все мои потоки пришли к 1 точке, а основной поток вступил во владение и продолжил дальше

m_Events.WaitOne();

Предел моего потока равен 3. Проблема, с которой я сталкиваюсь, несмотря наограничение пула потоков установлено в 3, мое приложение обрабатывает более 3 файлов одновременно, в то время как оно должно было обрабатывать только 3 файла одновременно.Пожалуйста, помогите мне решить эту проблему.

Ответы [ 4 ]

5 голосов
/ 16 мая 2011

Какой компьютер вы используете?

С MSDN

Вы не можете установить количество работников потоки или количество входов / выходов завершение темы на номер меньше чем количество процессоров в компьютер.

Если у вас 4 ядра, то самое маленькое, что вы можете иметь, - 4.

Также обратите внимание:

Если общеязыковая среда выполнения например, через Интернет Информационные службы (IIS) или SQL Сервер, хост может ограничить или предотвратить изменения размера пула потоков.

Если это веб-сайт, размещенный на IIS, вы также не можете изменить размер пула потоков.

4 голосов
/ 16 мая 2011

Лучшее решение предполагает использование Semaphore, который может ограничить одновременный доступ к ресурсу 1 . В вашем случае ресурс будет просто блоком кода, который обрабатывает рабочие элементы.

var finished = new CountdownEvent(1); // Used to wait for the completion of all work items.
var throttle = new Semaphore(3, 3); // Used to throttle the processing of work items.
foreach (WorkItem item in workitems)
{
  finished.AddCount();
  WorkItem capture = item; // Needed to safely capture the loop variable.
  ThreadPool.QueueUserWorkItem(
    (state) =>
    {
      throttle.WaitOne();
      try
      {
        ProcessWorkItem(capture);
      }
      finally
      {
        throttle.Release();
        finished.Signal();
      }
    }, null);
}
finished.Signal();
finished.Wait();

В приведенном выше коде WorkItem является гипотетическим классом, который содержит конкретные параметры, необходимые для обработки ваших задач.

Библиотека параллельных задач 1011 * значительно упрощает этот шаблон. Просто используйте метод Parallel.ForEach и укажите ParallelOptions.MaxDegreesOfParallelism, который ограничивает параллелизм.

var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 3;
Parallel.ForEach(workitems, options,
  (item) =>
  {
    ProcessWorkItem(item);
  });

1 Следует отметить, что я не люблю блокировать потоки ThreadPool с помощью Semaphore или любого другого блокирующего устройства. Это в основном тратит впустую нити. Возможно, вы захотите полностью переосмыслить свой дизайн.

2 голосов
/ 16 мая 2011

Вы должны использовать объект семафора для ограничения параллельных потоков.

1 голос
/ 16 мая 2011

Вы говорите, что файлы открыты: они на самом деле активно обрабатываются или просто остаются открытыми?Если вы оставляете их открытыми: были там, сделали это!Завершение соединения и ресурсов (в моем случае это было соединение с БД) для закрытия в конце области должно работать, но может потребоваться запуск утилизации / сборки мусора.

...