Типы сообщений с блоками DataFlow

Я занимаюсь самообучением TPL-Dataflow, и я читал, что использование неизменяемых объектов для сообщений - это путь.

Чтобы соответствовать этому, я разработал специальные классы для каждого входа и выхода блока.

К сожалению, когда я связываю свои блоки друг с другом, потому что типы ввода и вывода блоков очень разные, это приводит к размножению TransformBlock:

var proc1 = new TransformBlock<proc1In,proc1Out>(...
var convertOut1toIn2 = new TransformBlock<proc1Out,proc2In>(p1 => new proc2In { ... 
var proc2 = TransformBlock<proc2In,proc2Out>(...

proc1.LinkTo(convertOut1ToIn2);
convertOut1ToIn2.LinkTo(proc2);

Использование блоков Batch и Join позже для объединения результатов заставляет меня бороться с очень грязным кодом.

Во всех примерах, которые я читал в Интернете, используются простые типы, такие как int, string... Я не нашел ничего, что имело бы дело с немного более сложными типами.

Я чувствую желание использовать один большой объект и передать его ссылку через все блоки. Прежде чем совершить эту ошибку, я хотел бы знать, есть ли лучший способ сделать это.


person Larry    schedule 21.01.2016    source источник


Ответы (1)


После некоторого времени размышлений с TPL-Dataflow , Оказывается, что:

  • Представление о потоке данных как о конвейерной ленте, несущей производственные элементы к различным рабочим станциям, где элементы обогащаются и создаются, совершенно неверно: такой подход приводит к мучительным проблемам параллелизма. Dataflow — это система обмена сообщениями.

  • Вместо этого я чувствую, что лучше представить это как группу людей, которые имеют дело с внешними средствами для создания вещей (IO, сохраняемость базы данных, CalculationEngines...)

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

Моя проблема заключается в анализе нескольких изображений. Вместо того, чтобы блоки передавали объект «Workitem» друг другу и возились с ним, я предпочитаю вместо этого использовать отдельный класс «WorkItemSupplier». Этот класс использует ConcurrentDictionary рабочих элементов и предоставляет методы для работы с рабочими элементами.

Таким образом, мои блоки в Dataflow передают друг другу только идентификатор рабочего элемента, поэтому они могут использовать WorkItemSupplier в качестве внешнего средства для хранения/извлечения или изменения состояния любого рабочего элемента.

Таким образом, код работает более плавно, хорошо разделен и легче читается.

person Larry    schedule 23.01.2016
comment
Также помог этот вопрос много для фильтрации/объединения блоков из нескольких результатов. - person Larry; 26.01.2016