2013-11-13 3 views
2

Я использую разъем iDB2/iSeries для AS400 для получения сразу большого количества данных. Я создаю одно соединение с базой данных и, чтобы увеличить производительность, я использую этот вариант с несколькими потоками (примерно 10). Всего создано 50 команд и затем удаляется, и каждый DataReader закрыт.Должен ли я использовать несколько соединений, если я использую потоки для получения большого количества данных?

Все работает отлично, кроме одного: мне не удается закрыть это соединение. Я получил следующее исключение (первая строка означает «ссылка на объект не указывает на экземпляр объекта»):

{"La référence d'objet n'est pas définie à une instance d'un objet."} 
    [System.NullReferenceException]: {"La référence d'objet n'est pas définie à une instance d'un objet."} 
    Data: {System.Collections.ListDictionaryInternal} 
    HelpLink: null 
    HResult: -2147467261 
    InnerException: null 
    Message: "La référence d'objet n'est pas définie à une instance d'un objet." 
    Source: "IBM.Data.DB2.iSeries" 
    StackTrace: " à IBM.Data.DB2.iSeries.iDB2Connection.Close()\r\n à WcfApp.Metier.InitApp() dans c:\\projet\\WSApp.cs:ligne 450" 
    TargetSite: {Void Close()} 
+0

Выполняется ли исключение, если вы используете 'использование' вокруг соединения, а не явно вызываете' Close() '? Честно говоря, я не помню, как в последний раз, когда я когда-либо называл 'Close()' - 'using', было бы намного удобнее и надежнее. –

+0

Я использовал «использование», но действительно ли метод connection.dispose() закрывает соединение? Я так не думаю: если я сделаю это вручную, я вижу, что статус соединения по-прежнему «открыт». – Nicolas

+2

ни 'Закрыть', ни *' Dispose' действительно закрыть соединение - или, в зависимости от конфигурации, ** оба делают **. По умолчанию большинство провайдеров используют пул соединений, поэтому как 'Close', так и' Dispose' просто помещают * базовое * соединение обратно в доступный пул. Было бы недоразумением думать, что 'Dispose' делает что-то неправильно или другое здесь. Если объединение соединений отключено (обычно в строке соединения), то как 'Close', так и' Dispose' завершат базовое соединение. –

ответ

2
  1. Использование Task вместо Thread сделает вашу обработку данных более прозрачной и понятной.
  2. Заботьтесь о совместном использовании - используйте инструкцию lock, если необходимо.
  3. Ознакомьтесь с пулами транзакций и подключений - это то, что вам нужно знать при использовании соединений с БД.
+0

Я заменяю все потоки задачами: не уверен, что это что-то изменит, но код станет намного понятнее! Благодарю. Я читаю по вашему совету: я скоро вернусь;). Небольшой вопрос: действительно ли мне нужны блокировки, если я не обновляю/вставляю/не удаляю? – Nicolas

+2

@Nicolas, если вы получаете доступ к одному соединению из нескольких потоков, тогда да: абсолютно. Соединения обычно не предназначены для одновременного доступа, поэтому «lock» здесь просто синхронизирует доступ к самому соединению. Если вы * не * используете одно и то же соединение из нескольких потоков, то: no. –

Смежные вопросы