Как распространить потолок сообщений на все блоки потока данных?

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

Например, я могу начать с настраиваемого блока потока данных, который связан с буферным блоком. Этот буферный блок связан с блоком действий, очередь которого, как мне хотелось бы, не превышала определенное количество элементов в очереди. Как я могу запретить очередям в производящем блоке потока данных или буферном блоке когда-либо хранить все больше и больше элементов в своей собственной очереди, зная, что последний блок потока данных в цепочке не может потреблять больше элементов в определенный момент времени и что inQueue не может принимать больше элементов ?


person Matt    schedule 11.07.2012    source источник


Ответы (1)


Нет никакого «умного» способа сделать это, вам просто нужно установить BoundedCapacity в параметрах каждого блока при их создании.

Я думаю, что есть несколько причин, по которым то, что вы предлагаете, не сработает:

  1. Как именно блок должен определять, какой должна быть его емкость? Тот факт, что ActionBlock имеет емкость 100, не означает, что BufferBlock перед ним должны иметь такую ​​же емкость. Это то, что должен решить человек.
  2. Параметры блоков не могут быть изменены после создания. Чтобы сделать то, что вы хотите, вам потребуется изменить параметры.

При этом я думаю, что в вашем простом случае вы могли бы просто избавиться от BufferBlock и отправить элементы из производящего блока прямо в ActionBlock.

person svick    schedule 11.07.2012
comment
Я использую буферный блок в подклассах, чтобы центральный вызывающий класс мог установить связь между общедоступным буферным блоком, каждый из которых содержится в нескольких подклассах. Есть ли лучшие идеи, как связать один блок потока данных с другим блоком потока данных в другом классе? - person Matt; 11.07.2012
comment
Я не понимаю, зачем тебе BufferBlock для этого. Почему бы вам просто не выставить внутренний блок как ITargetBlock? - person svick; 11.07.2012
comment
немного связанный, но другой вопрос (не уверен, что он требует нового вопроса): есть ли способ очистить очереди любых / всех блоков потока данных, если поток прерывается, Ctrl + C в приложении консоли Windows или при простом выходе из программа, пока в некоторых очередях еще есть предметы? Проблема в том, что, хотя приложение полностью закрывается, при следующем запуске мне кажется, что в некоторых очередях все еще есть старые элементы из предыдущего запуска. Я очень озадачен этим. Есть ли что-то похожее на TPL Task CancellationToken? - person Matt; 11.07.2012
comment
Я сделал это на самом деле, буферные блоки были просто упрощенным примером. - person Matt; 11.07.2012
comment
Вы можете установить _ 1_ в параметрах каждого блока. Но я не уверен, что это поможет вам, нет автоматического сохранения, поэтому, если кажется, что есть элементы, говорящие в очередях даже после перезапуска приложения, происходит что-то еще. - person svick; 11.07.2012
comment
Если я позволю приложению работать, пока оно не выйдет само, у меня не будет проблем, но если я отменю приложение с помощью ctrl-c, я буду иметь дело со старыми элементами из предыдущего запуска. Я запускаю FileStream и BinaryReader в блоке данных, может ли это быть связано с этим? Может быть, кеш или буфер ввода-вывода не сбрасываются? - person Matt; 11.07.2012
comment
Повторите ваш комментарий ITargetBlock, я попробовал его, но для моего проекта мне, вероятно, нужно использовать IPropagatorBlock, потому что я отправляю в него элементы и использую его для ссылки на другой блок данных. Верный? - person Matt; 11.07.2012
comment
извините, пожалуйста, игнорируйте вещь CancellationToken, я немного поправил блоки потока данных и, хотите верьте, хотите нет, вручную не перестраивал код в VS (я исходил из предположения, что запуск кода в режиме отладки всегда перестраивается перед запуском код), извините мой плохой. - person Matt; 11.07.2012