c # Поток данных или задачи, потребляющие сообщения для параллельной обработки

Если я хочу получать сообщения из внешней очереди, скажем, в Redis или подобном. Не лучше ли, чтобы один поток постоянно проверял очередь и отправлял сообщения в соответствующий BroadcastBlock для обработки (например)

if (message.type == "person")
    personBroadcast.post(message);
else
    monsterBroadcast.post(message);

Которые затем будут транслироваться в конвейеры для обработки, или лучше иметь, скажем, 4 Tasks, которые все берут сообщения из очереди и обрабатывают их сами?

Во-первых, будут ли блоки TPL DataFlow обрабатываться параллельно, или они все равно должны быть в отдельных задачах? Я пытаюсь решить, какой подход будет наилучшим образом использовать ресурсы. Совет ценится.


person user2788307    schedule 18.09.2013    source источник


Ответы (2)


Это гораздо проще сделать с помощью отфильтрованных ссылок между блоками:

// this can be a BroadcastBlock too
var broadCastBlock = new BufferBlock();

// filter only persons
broadCastBlock.LinkTo(personBroadcast, m => m.type == "person");

// send all other messages as monsters
broadCastBlock.LinkTo(monsterBroadcast);

Каждому блоку соответствует задача, которая выполняется в пуле потоков. По умолчанию задача не перезапускается, но вы можете изменить это поведение с помощью DataflowBlockOptions.MaxMessagesPerTask. Это не повлияет на задачу Completion.

Так что никаких дополнительных задач для TPL Dataflow вам не нужно, так как нужные он создаст сам.

person VMAtm    schedule 24.03.2017

Ваш вариант использования звучит как один из тех, где может пригодиться структура разрушителя. В двух словах, Disruptor использует один поток для прослушивания событий и их последующей отправки обработчикам (широковещательные блоки в вашем определении). Вы можете найти версию Disruptor для .net по адресу https://code.google.com/p/disruptor-net/

person undefined    schedule 23.09.2013