У меня есть программа на C #, в которой есть «Агент» класс. Программа создает несколько агентов, и у каждого агента есть метод " run () ", который выполняет задачу (т. Е. Task.Factory.StartNew () ...).
Каждый агент выполняет некоторые вычисления, а затем должен дождаться, пока все другие агенты завершат свои вычисления, прежде чем перейти к следующему этапу (его действия будут основаны на расчетах других).
Чтобы заставить агента ждать, я создал CancellationTokenSource (названный «tokenSource»), и чтобы предупредить программу о том, что этот агент будет спать, я вызвал событие. Таким образом, 2 последовательные команды:
(1) OnWaitingForAgents(new EventArgs());
(2) tokenSource.Token.WaitHandle.WaitOne();
(Событие перехватывается классом «AgentManager» , который сам по себе является потоком, а 2-я команда переводит поток задач агента в спящий режим до получения сигнала для токена отмены).
Каждый раз, когда указанное событие инициируется, класс AgentManager перехватывает его и добавляет +1 к счетчику. Если номер счетчика равен количеству агентов, используемых в программе, AgentManager (который содержит ссылку на все агенты) активирует каждого из них следующим образом:
agent.TokenSource.Cancel();
Теперь мы подошли к моей проблеме: 1-я команда выполняется асинхронно Агентом, затем из-за переключения контекста между потоками AgentManager, похоже, перехватывает событие и продолжает активировать всех Агентов. НО - текущий Агент еще даже не достиг 2-й команды!
Таким образом, Агент получает сигнал «проснуться», и только тогда он ложится спать, а это значит, что он застревает во сне, и никто его не разбудит!
Есть ли способ «атомизировать» два последовательных метода вместе, поэтому переключение контекста не произойдет, что заставит Агента перейти в спящий режим до того, как AgentManager сможет его разбудить?