Ваш вопрос выглядит как обычная техника разветвления. Каждый раз, когда вы бы повторили, вместо этого вы запускаете другую параллельную операцию (ставьте ее в очередь потоков и т. Д.). Но вам нужно дождаться окончания всех ветвей в конце. Просто добавьте 1 к событию обратного отсчета для каждой подоперации, которую вы запускаете, и сообщите об этом в конце каждой подоперации. Это безопасно делать до тех пор, пока вы настроите алгоритм, поэтому он не будет сигнализировать, пока не добавит для каждой дочерней операции.
Я должен добавить, что вам не нужно знать заранее счет, просто сделайте 1 в корне, и каждый раз, когда вы переходите к ребенку, добавляйте 1, а затем сигнализируйте на конец каждого, и он будет динамически обрабатывать любое дерево без предварительной оплаты.
В CountdownEvent есть метод Add, который позволяет увеличивать счет в полете.
Это имеет смысл? Возможно, я не в курсе того, что вы пытаетесь достичь.
Однако, если вы действительно хотите CountdownEvent, который ведет себя так, как вы указали, довольно просто обернуть пару взаимосвязанных операций в классе, чтобы сделать то, что вы говорите.
Тем не менее, CountdownEvent создан так, чтобы быть легковесным, он почти бесплатен, если никто не ждет, пока не будет подан сигнал. В дорогом случае это оптимально, независимо от того, сколько задач (и т. Д.) Ему потребуется только для одного перехода ядра в сигнал и одной для ожидания, в худшем случае.
Для реализации того, что вы предлагаете, потребуется синхронизация вокруг сигнализации и сброса события. Событие обратного отсчета основывается на одном простом принципе, только переход от ненулевого к нулю при вызове Сигнала может сигнализировать о событии. Расы не существует, поскольку более чем один поток не может изменить значение за один раз (он заблокирован), поэтому только один поток может попытаться сигнализировать объект события (который пробуждает другой ожидающий поток). Идеально подходит.
Однако, если у вас есть несколько потоков, которые устанавливают и сбрасывают его, вам нужно синхронизировать все настройки и сбрасывать, так как счетчик может колебаться пару раз, и несколько потоков будут одновременно пытаться установить или сбросить событие. (Установка, сброс и ожидание события - все это дорого, потому что все они должны выполнить переход ядра и вызвать переключение контекста). Это не сработает, если вы не синхронизируете что-то, чтобы защитить переходы установки / сброса. Если бы они добавили это в CountdownEvent, это больше не было бы почти оптимальным, это было бы значительно дороже.