Какой тип очереди использовать при параллельной обработке данных - C # - .NET 4 - PullRequest
6 голосов
/ 14 апреля 2011

Сценарий: данные принимаются и записываются в базу данных с отметками времени.Мне нужно обработать необработанные данные в порядке, полученном на основе метки времени, и записать их обратно в базу данных, другую таблицу, снова поддерживая порядок на основе метки времени.

Я придумал следующую схему: создал две очереди, одну для хранения необработанных данных из базы данных, другую для хранения обработанных данных перед их записью в БД.У меня есть два потока, одно чтение в исходную очередь и другое чтение из очереди результатов.Между ними я порождаю несколько потоков для обработки данных из исходной очереди и записи их в очередь результатов.

Я экспериментировал с SortedList (ручная блокировка) и BlockingCollection.Я использовал два подхода к параллельной обработке: Parallel.For (ForEach) и TaskFactory.Task.StartNew.

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

Недавно я узнал о OrderingPartitioner и подумал, что это решит проблемуно, следуя примеру MSDN, я вижу, что это не сортировка базовой коллекции.Может быть, мне нужно реализовать пользовательский разделитель, чтобы заказать мою коллекцию сложных типов данных?или, может быть, есть лучший способ решения проблемы?

Любые предложения и / или ссылки на статьи, обсуждающие подобную проблему, высоко ценятся.

Ответы [ 3 ]

5 голосов
/ 14 апреля 2011

Лично я по крайней мере попытался бы начать с использования BlockingCollection<T> для ввода и ConcurrentQueue<T> для результатов.

Я бы использовал Parallel Linq для обработки результатов. Чтобы сохранить порядок во время обработки, вы можете использовать AsOrdered () в операторе PLINQ.

2 голосов
/ 14 апреля 2011

Рассматривали ли вы PLINQ и AsOrdered ()?Это может быть полезно для того, чего вы пытаетесь достичь.http://msdn.microsoft.com/en-us/library/dd460719.aspx

0 голосов
/ 14 апреля 2011

Возможно, вы рассмотрели эти вещи, но ...

Почему бы просто не передать метку времени в базу данных, а затем либо позволить базе данных выполнить упорядочение, либо исправить порядок в базе данных после всех потоков обработкивернулись?У операторов sql есть для последовательного выполнения?

PLINQ - это здорово, но я бы постарался избежать требований к синхронизации потоков и просто передать больше данных об упорядочении в базу данных, если вы можете.

...