2010-11-06 2 views
1

Я бы хотел использовать многопоточность, когда мы записываем данные из базы данных в наши собственные объекты. В настоящее время мы используем Firebird и извлекаем данные, используя «только для чтения» FbDataReader.C# Многопоточный доступ к базе данных для Firebird (.NET)

Мы просматриваем записи, хранящиеся в FbDataReader, и заполняем объект, добавляя объект в список, который затем используется в приложении. Все это происходит на уровне доступа к данным нашего приложения.

В идеале мы хотели бы получить данные из базы данных (в FbDataReader), а затем разделить работу по записи объектов (по одной на строку) между потоками. Проблема, которую я вижу, заключается в том, что FbDataReader имеет только пересылку, а разные потоки могут заставить читателя выполнить следующую запись до того, как будет завершен другой поток.

Решение может заключаться в том, чтобы сбрасывать FbDataReader в индексированный список, массив или словарь, но это было бы дорого.

Есть ли у кого-нибудь идеи или мы просто тратим наше время на реорганизацию этой части нашего кода?

ответ

0

Если вы можете получить большие блоки непрерывных записей, которые не накладываются друг на друга, и назначить для каждого объекта данных для чтения, то вы можете использовать поток для каждого считывателя и получать прибыль, если источник данных не вызывает горлышко бутылки. В основном вы будете использовать несколько объектов считывателя вместо промежуточного хранилища.

например.

where ID >= 0 && ID < 10000 << block 1 for data reader instance 1 
where ID >= 10000 && ID < 20000 << block 2 for data reader instance 2 
where ID >= 20000 && ID < 30000 << block 3 for data reader instance 3 

Этот пример из трех читателей позволит вам создать три объекта одновременно.

Если вы дополнительно используете C# iterator, обернутый вокруг всего этого процесса, у вас может быть способ вернуть все объекты, как если бы они были единой коллекцией, без использования промежуточного хранилища для экземпляров.

foreach (object o in MyIterator()) { .... 

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

+0

Я понимаю, что использование прямого курсора не может идти быстрее, чем одна строка за раз. Вот почему я предложил промежуточный шаг назначения всех данных индексированному массиву, списку или словарю, которые можно разделить между потоками. – Mysaffy

+0

Простите за риторические вопросы; они не собирались оскорблять. Просто прислушаться ко всем остальным о том, чтобы вообще заглянуть в эту тему. Вы правы, очевидно, что вы понимаете необходимость посредников. –

+0

Так задает вопрос. Как бы вы быстро сбросили FbDataReader в список, массив или словарь. Кажется, что нет способа ускорить этот процесс. Спасибо за ваш вклад до сих пор, его оценили. – Mysaffy

0

Вы можете попытаться создать новый поток и создать там новое соединение с базой данных на основе существующей строки подключения. В одном потоке вы можете выполнить четные записи (2,4,6 и т. Д.), А в другом - нечетные записи (1,3,5 и т. Д.). Однако это увеличит сложность вашего кода.

Для операций с большими объемами данных Я предпочитаю создавать новый объект подключения к базе данных для выполнения работы в отдельном потоке и отображать прогресс для пользователя, так что поток пользовательского интерфейса не замерзает, и приложение остается отзывчивым.