Как я могу разветвить логику в потоке данных TPL?

Я новичок в потоке данных TPL, поэтому простите меня, если это простой вопрос.

У меня есть блок входного буфера, который принимает базовый класс. Как я могу перейти оттуда к блоку на основе производного типа? Так, например:

var inputBlock = new BufferBlock<EventBase>();
//if EventBase is Meeting then go to block X
//if EventBase is Appointment the go to block Y

Спасибо!


person jmichas    schedule 02.09.2014    source источник
comment
Вы не знаете. В этом весь смысл полиморфизма. Каждый производный тип должен переопределять члены базового типа таким образом, чтобы различать поведение с использованием членов базового типа.   -  person Servy    schedule 02.09.2014
comment
Так ты говоришь, что нет способа сделать это? Я могу сделать это вне потока данных TPL в цикле, и только если (EventBase is Meeting) {}, я спрашиваю, как это делается в блоках потока данных? Нужен ли мне специальный блок?   -  person jmichas    schedule 02.09.2014
comment
Я не говорю вам, что это невозможно, я говорю вам, что это плохая идея. Это свидетельствует о плохой конструкции. Вы не должны этого делать. Вместо этого вы должны спроектировать блоки для поддержки любого типа EventBase за счет использования полиморфизма.   -  person Servy    schedule 02.09.2014


Ответы (2)


Вы можете отправить предикат в метод LinkTo, чтобы различать элементы. Однако вам нужно будет выполнить понижающее преобразование из EventBase внутри каждого блока, чтобы использовать логику, специфичную для этого типа:

var inputBlock = new BufferBlock<EventBase>();
var meetingBlock = new ActionBlock<EventBase>(
    eventBase =>
    {
        var meeting = eventBase as Meeting;
        //...
    });
var appointmentBlock = new ActionBlock<EventBase>(
    eventBase =>
    {
        var appointment = eventBase as Appointment;
        //...
    });

inputBlock.LinkTo(meetingBlock, eventBase => eventBase is Meeting);
inputBlock.LinkTo(appointmentBlock, eventBase => eventBase is Appointment);

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

person i3arnon    schedule 02.09.2014
comment
Спасибо, это похоже на то, что я ищу. И я понимаю, что вы, ребята, говорите о плохом дизайне, к сожалению, я во власти вышестоящего провайдера, и их xml-фрагменты несколько плохо спроектированы, поэтому, чтобы облегчить мои проблемы с десериализацией, я создал xml-массив «событий», который имеет узлы встреч и встреч. было проще всего десериализовать с помощью базового класса и таким образом разветвить логику для обработки. Там вполне может быть лучший дизайн, но на данный момент я довольно далеко и не хочу возвращаться к коду десериализации. - person jmichas; 02.09.2014

Если вам нужно более простое решение и вы не возражаете против использования вспомогательной библиотеки, созданной на основе потока данных TPL, есть DataflowEx, который предоставляет метод LinkSubTypeTo().

Dataflow<TIn, TOut> flow1;
Dataflow<TOutSubType1> flow2;
Dataflow<TOutSubType2> flow3;

flow1.LinkSubTypeTo(flow2);
flow1.LinkSubTypeTo(flow3);

Пожалуйста, проверьте раздел расширенные ссылки документа библиотеки. Внутри он использует тот же механизм, который представил @I3arnon.

Отказ от ответственности: я являюсь автором DataflowEx.

person Dodd    schedule 20.12.2014