Пул потоков, порядок выполнения и длительные операции - PullRequest
4 голосов
/ 22 сентября 2010

Мне нужно создать несколько потоков обработки в новом приложении. Каждый поток имеет возможность быть «долго работающим». Кто-нибудь может прокомментировать жизнеспособность встроенного пула потоков .net или какого-либо существующего пользовательского пула потоков для использования в моем приложении?

Требования:

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

Возможность раскручивать несколько потоков.

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

Зависшие темы могут быть обнаружены и уничтожены.

EDIT:

Кажется, что комментарии ведут к ручному созданию потоков. К сожалению, я придерживался версии 3.5. Threadpool был привлекательным, потому что это позволило бы мне работать в очереди и создавать потоки, созданные для меня, когда ресурсы были доступны. Есть ли хороший 3.5 совместимый шаблон (возможно, производитель / потребитель), который дал бы мне этот аспект пула потоков без фактического использования пула потоков?

Ответы [ 3 ]

6 голосов
/ 22 сентября 2010

Ваши требования по существу исключают использование .NET ThreadPool;

Как правило, его не следует использовать для длинных потоков, из-за опасности истощения пула.

Этооднако, он хорошо работает в службах Windows, и вы можете раскрутить несколько потоков - автоматически ограниченных пределами пула.

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

Нет простых способов обнаружить и уничтожить запущенные потоки в ThreadPool

Итак, по сути, вы захотите посмотреть за пределы ThreadPool;Я мог бы порекомендовать вам, возможно, вам понадобятся «полные» System.Threading.Thread экземпляры только из-за всех ваших требований.Пока вы обрабатываете проблемы параллелизма (как и в случае с любым механизмом потоков), я не считаю, что класс Thread действительно очень сложен для управления, на самом деле.

1 голос
/ 22 сентября 2010

Я сделал по сути то же самое с .Net 3.5, создав собственный менеджер потоков:

  1. Создание рабочих классов, которые знают, как долго они работают.
  2. Создайте потоки, которые запускают рабочий метод, и добавьте их в Queue<Thread>.
  3. . Поток супервизора считывает потоки из очереди и добавляет их в Dictionary<int, Worker>, когда он запускает их, пока не достигнет своих максимальных работающих потоков.Добавьте поток в качестве свойства экземпляра Worker.
  4. Когда каждый работник завершает свою работу, он вызывает метод обратного вызова из супервизора, который передает его ManagedThreadId.
  5. Супервизор удаляет поток из словаря изапускает еще один ожидающий поток.
  6. Опросите словарь запущенных рабочих, чтобы узнать, истек ли какой-либо из них, или поместите таймеры в рабочие, которые вызывают обратный вызов, если они занимают слишком много времени.
  7. Сигнал долго- запуск работника для выхода или прерывания его потока.
  8. Супервизор вызывает обратные вызовы для вашего основного потока, чтобы сообщить о прогрессе и т. д.
1 голос
/ 22 сентября 2010

Простой ответ, но класс Task (Fx4) отвечает большинству ваших требований.

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

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

...