Обработка больших объемов данных с использованием многопоточности

Мне нужно написать службу С# (это может быть служба Windows или консольное приложение), которая должна обрабатывать большие объемы данных (100 000 записей), хранящихся в базе данных. Обработка каждой записи также является достаточно сложной операцией. Мне нужно выполнить много вставок и обновлений как часть обработки.

Мы используем NHibernate в качестве ORM.

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

Может ли кто-нибудь дать мне несколько советов о том, как я должен подходить к этому ... учитывая, что я использую NHibernate и каковы возможные ошибки, такие как тупик и т. Д.

Большое спасибо.


person Sennin    schedule 17.03.2011    source источник
comment
Небольшой несвязанный момент - ваш вопрос на самом деле не является вопросом «С#», поэтому я бы, вероятно, удалил этот тег; и поскольку вы упомянули NHibernate и из-за характера вопроса, я бы, вероятно, добавил это как тег. Если вы хотите показать, что находитесь в .NET, добавьте тег .NET.   -  person DuckMaestro    schedule 17.03.2011
comment
Спасибо .. точка принята :)   -  person Sennin    schedule 17.03.2011
comment
Где вы храните данные, которые вы обработали? 100 000 отдельных операторов обновления убьют вашу базу данных.   -  person M Afifi    schedule 17.04.2012
comment
любое решение с полным образцом исходного кода?   -  person Kiquenet    schedule 22.08.2012


Ответы (4)


Вам следует рассмотреть возможность использования библиотеки параллельных задач.

person Pradeep    schedule 17.03.2011

Предполагая, что вы используете .NET 4.0, вы можете использовать библиотеку параллельных задач (как уже упоминалось), чтобы сделать что-то вроде этого:

Parallel.ForEach(sourceCollection, item => Process(item));

Ваша исходная коллекция будет состоять из IEnumerable загруженных записей. Библиотека сделает все за вас:

Исходная коллекция разбита на разделы, и работа запланирована для нескольких потоков в зависимости от системной среды. Чем больше процессоров в системе, тем быстрее работает параллельный метод.

Может быть полезно прочитать руководство по использованию Parallel.ForEach(). Кроме того, помните о потенциальных ловушках.

person Jonathan Freeland    schedule 17.03.2011
comment
Спасибо, Джон, и всем вам, ребята, за ваши предложения. Я просто смотрю на параллельную библиотеку задач. Мне интересно, как я буду управлять сеансами NHibernate здесь, поскольку у меня нет контроля над параллельными потоками. В идеале я хотел бы, чтобы каждый параллельный поток имел свой собственный сеанс... какие-нибудь мысли о том, как это можно сделать с помощью TPL? - person Sennin; 17.03.2011

Похоже, PLINQ — лучшее решение (глава 5 этой статьи). Но поскольку каждый расчет много работает с базой данных, вам следует создать отдельный сеанс для каждого потока.

person Alex Zhevzhik    schedule 17.03.2011

По возможности используйте IStatelessSessions и поэкспериментируйте со свойством adonet.batch_size.

Кроме того, насколько производительным он должен быть? Я поклонник NH, но это один из сценариев, в котором хранимые процедуры могут быть лучше.

person Jason Freitas    schedule 17.03.2011
comment
Как всегда, требуется высокая производительность :) .. однако я не слишком заинтересован в переносе всей бизнес-логики в sproc - person Sennin; 17.03.2011