Справочная информация: я работаю над приложением, в котором уже разработана система потоков.Это далеко от оптимального, но я не могу переделать это в настоящее время.Он не использует ни одну из более новых конструкций потоков из .net, только базовые Thread
объекты и объекты, обертывающие логику обработки потока.
Общая настройка этого: (есть две группы, иликатегории потоков прямо сейчас)
Главный поток приложения (главная тема), который порождает рабочие потоки.
Рабочие потоки.Каждый из них имеет объект Thread
и рабочий объект, который выполняет всю обработку / обрабатывает границу между потоками и т. Д. Каждый поток выполняет задания, а каждое задание имеет JobTypeID
.
Мне нужно ввести третий тип потока, один для управления рабочими.Эти управляющие сообщения будут поступать из веб-службы wcf (поэтому этот поток обрабатывается неявно).
Управляющими сообщениями являются: {Pause / Resume, List-of-IDs}
Моя цель:
Я пытаюсь выяснить, как лучше всего синхронизировать эти потоки, чтобы, если поток обрабатывал задание, и приходило сообщение о приостановке всех заданий этого JobTypeID
, он должен блокироваться до отправки резюме (для этого идентификатора).Уловка здесь в том, что во время отправки сообщения никакие соответствующие задания не могут быть обработаны, поэтому не нужно предпринимать немедленных действий, и у меня также нет списка рабочих объектов, поэтому я не могу простопереберите каждого работника и выполните if-match-then-pause.
Актуальный вопрос (обобщенно) Что бы вы, ребята, посоветовали сделать для синхронизации набора рабочих потоков, spawner / managerпоток и набор контрольных потоков?
вещи, которые я пробовал
Один из подходов заключается в хранении коллекции ManualResetEvent
объектов, по одному на JobTypeID
и сигнализировать и ждать их в соответствии с входящими сообщениями.Что вы думаете об этом подходе?Я не могу найти какую-либо информацию о передовых методах или затратах на память / обработку для наличия более 100 дескрипторов ожидания в процессе.
Другой подход состоит в том, чтобы иметь один объект, для которого все потоки будут ожидать,синхронизированная коллекция JobTypeIDs
, которая должна ждать.У меня были некоторые проблемы с этим подходом.Использование ManualResetEvent
означает, что если я возобновляю один идентификатор задания, но другие ожидают, я должен сделать set (); reset ();, и это вызывает некоторые условия гонки (даже если я пытаюсь сделать WaitHandle.SignalAndWait (x, x)) Наконец, я нашел решение, использующее Monitor.PulseAll (), которое работает.
Я также мог бы использовать монитор с множеством объектов блокировки - кажется, он будет более легким, чем множестворучки ожидания.
Также, извините за длинный вопрос и спасибо за чтение!