Установка заказа задач с использованием задач .NET 4.0 Параллельные библиотеки
-
27-09-2019 - |
Вопрос
У меня есть программа, которая имеет тонну датчиков, создающих данные по довольно высокой скорости, и потребители, которые должны потреблять ее. Потребители потребляют по очень разным ставкам.
Поскольку я использую iobserver / iobsivable, тривиальное решение было просто создать задачу для каждого события и обернуть annext () вызов и данные в лампе. Это очень хорошо работало, я был удивлен, как мало накладных расходов было над сырыми звонками.
Проблема в том, что некоторые из этих потребителей нуждаются в порядок событий, строго принудившихся и не могут пропустить какие-либо события. «Перферфесть» не достаточно хорош.
Лучшее решение, которое я придумал, вместо того, чтобы упаковать событие / onnext () пару, чтобы обернуть вставку в параллельную точку, одну очередь на потребителя и иметь резьбу на другом конце очереди, чтобы сделать annext () звонки.
Три непосредственных проблемы с этим подходом. Это много, намного медленнее, чем задача / onnext () обертерное решение. Нет блокировки декабря (или нет?) Для параллельцеи, поэтому реализация немного сложно. Третий - это то, что это кажется такой общей проблемой, которую я не могу себе представить, что не может привести к обеспечению заказа, что я пропустил, может быть, что-то вроде нескольких заводов задач, разделяющих основной пул, каждый завод с некоторыми настройками, который делает их строго принудительным порядок.
Кто-нибудь знает правильный способ достичь того, что я пытаюсь сделать?
Редактировать: Любое решение, которое включает в себя нить на потребитель или производитель, не работает. Производители / потребители образуют длинные цепи, есть сотни каждого.
Решение
То TPL DataFlow Библиотека может быть хорошо подходит для вашего приложения. Он расширяет TPL с парадигме данных DataFlow, которая позволяет настроить график обработки и работать в среде выполнения высокопроизводительной.
TPL Dataflow доступен в качестве библиотеки на вершине .NET 4 и должен отправить как часть .NET 4.5.
Другие советы
Нет комментариев на лучшую абстракт для обеспечения частичного заказа, но если вы используете BlockingCollection<T>
обертка вокруг А. ConcurrentQueue<T>
, это даст вам блокировку Take
Операция для учета элементов. например:
// the default is ConcurrentQueue, so you don't have to specify, but if you
// wanted different behavior you could use e.g. ConcurrentStack
var coll = new BlockingCollection<int>(new ConcurrentQueue<int>());
coll.Add(5); // blocks if the collection is at max capacity
int five = coll.Take(); // blocks if the collection is empty