Странное исключение Npgsql

Это пример, приведенный в руководстве. Когда я пытаюсь сделать то же самое, я получаю множество исключений. В чем ошибка в этом.

using(NpgsqlConnection conn = new NpgsqlConnection("connstring"))
{
    conn.Open();
    using(NpgsqlCommand command = new NpgsqlCommand("select command", conn))
    {
        command.Parameters.Add(new NpgsqlParameter("column1", NpgsqlDbType.Integer);
        command.Parameters[0].Value = 4;
        using(NpgsqlDataReader dr = command.ExecuteReader())
        {
            dr.Read();
            Console.Write("{0} \t", dr[0]);
        }
    }
}

Исключение :

System exception System.IO.IOException: I/O error occurred.
at Npgsql.NpgsqlState.<ProcessBackendResponses_Ver_3>d__a.MoveNext()
at Npgsql.NpgsqlState.IterateThroughAllResponses(IEnumerable`1 ienum)
at Npgsql.NpgsqlState.Query(NpgsqlConnector context, NpgsqlCommand command)
at Npgsql.NpgsqlConnector.Query(NpgsqlCommand queryCommand)
at Npgsql.NpgsqlConnector.ReleaseRegisteredListen()
at Npgsql.NpgsqlConnector.ReleaseResources()
at Npgsql.NpgsqlConnectorPool.UngetPooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
at Npgsql.NpgsqlConnectorPool.ReleasePooledConnectorInternal(NpgsqlConnection Connection, NpgsqlConnector Connector)
at Npgsql.NpgsqlConnectorPool.ReleasePooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
at Npgsql.NpgsqlConnectorPool.ReleaseConnector(NpgsqlConnection Connection, NpgsqlConnector Connector)
at Npgsql.NpgsqlConnection.Close()
at Npgsql.NpgsqlConnection.Dispose(Boolean disposing)
at System.ComponentModel.Component.Dispose()

Теперь это работает корректно. Какая разница :

using(NpgsqlConnection conn = new NpgsqlConnection("connstring"))
{
    conn.Open();
    using(NpgsqlCommand command = new NpgsqlCommand("select command", conn))
    {
        command.Parameters.Add(new NpgsqlParameter("column1", NpgsqlDbType.Integer);
        command.Parameters[0].Value = 4;
        NpgsqlDataReader dr = command.ExecuteReader();            
        dr.Read();
        Console.Write("{0} \t", dr[0]);
    }
}

почему datareader нельзя использовать с Idisposable?


person King    schedule 21.12.2011    source источник
comment
Получаете ли вы какие-либо результаты до исключения и есть ли ошибки в журналах postgres? NpgsqlState.IterateThroughAllResponses занимается анализом ответов на запросы, не дающие результатов, и при очистке соединения отправляются внутренние запросы. Однако я думаю, что здесь либо в Npgsql есть ошибка, либо в вашем коде есть ошибка (возможно, ваша строка подключения или запрос, который вы не указываете в своем примере кода, и есть ошибка), и тогда Npgsql плохо справляется с этим с помощью сообщение от его внутренних органов, а не хорошее объяснение проблемы.   -  person Jon Hanna    schedule 21.12.2011
comment
Кроме того, не могли бы вы показать свои настоящие "connstring" и "select command" только с именем пользователя, именем сервера и паролем, измененными на XXXX. Очевидно, вы не хотите публиковать это, но проблема может заключаться в этом.   -  person Jon Hanna    schedule 21.12.2011
comment
Кажется, это проблема в Npgsql, где он неправильно обрабатывает ситуацию с ошибкой. Странная часть заключается в том, почему вы получаете IOExceptions при удалении соединения. Вы отключаетесь от сервера во время работы вашей программы?   -  person Francisco Junior    schedule 21.12.2011
comment
@FranciscoJunior: я отредактировал вопрос, потому что он работает, если устройство чтения данных не используется с использованием (это не является одноразовым). Пожалуйста, проверьте и предложите, почему это не происходит должным образом.   -  person King    schedule 21.12.2011
comment
Все любопытнее и любопытнее. Во всяком случае, должно быть наоборот. Это определенно неправильно для Npgsql. В вашем коде может быть ошибка (опять же, мы можем видеть настоящие строки?), а может и нет, но в любом случае Npgsql не должен реагировать так. Это определенно один из списка ошибок.   -  person Jon Hanna    schedule 22.12.2011
comment
connstring = Server = 127.0.0.1; Порт = 6001; Идентификатор пользователя = test_test; Пароль = xxxxx; база данных = db_test, и запрос выбирает столбец 1 из таблицы 1, где id = xvalue, и иногда я использую процедуры, выберите значение 1, значение 2 из schema.function ( :xvalue,:yvalue), а затем добавить к нему параметры. Вопрос в том, почему он работает, когда он не удален, и почему не для использования (NpgsqlDataReader dr = command.ExecuteReader()). Это повод для беспокойства!   -  person King    schedule 22.12.2011
comment
@FranciscoJunior В руководстве по NPGSQL есть программа, похожая на мою программу. В чем может быть проблема, чтобы это возникло?   -  person King    schedule 22.12.2011
comment
Если сервер отключается после возврата результата, NPGSQL становится странным. Это случай, когда ситуация не обрабатывается внутри NPGSQL.   -  person King    schedule 22.12.2011
comment
Почему вы отправляете запрос «выберите 1 как ConnectionTest\x00». Я имею в виду, какой сценарий нужен?   -  person King    schedule 22.12.2011
comment
Когда соединение возвращается в пул соединений, NPGSQL отправляет «unlisten *» и «select 1 as ConnectionTest\x00». Кажется, это нехорошо. Это не сэкономит мне время.   -  person King    schedule 22.12.2011
comment
Привет, я попробовал ваш образец здесь и не смог воспроизвести проблему, как у вас. Я пробовал Mono и Windows 7. Какую версию Npgsql вы используете и какую среду выполнения? Что касается выбора 1, это делается для проверки работоспособности соединения, прежде чем возвращать его обратно в пул. unlisten * должен очистить любое уведомление, которое может быть настроено клиентским приложением, чтобы соединение возвращалось чистым в пул.   -  person Francisco Junior    schedule 22.12.2011
comment
Также обратите внимание, что в вашем отредактированном примере вы не закрываете читалку. Не могли бы вы попробовать закрыть его, чтобы увидеть, не появится ли проблема снова?   -  person Francisco Junior    schedule 22.12.2011
comment
Но пример в руководствах не указывает на это. И более того, делая ридер одноразовым, его все равно безопасно утилизируют. Я исправил это, заставив сервер отключиться от этого еще на несколько секунд. Но я предлагаю вам обработать это исключение. Я бы посоветовал вам загрузить тест с параллельными потоками и еще несколькими последовательными (большими нагрузками) и отключением на стороне сервера. Вы сможете воспроизвести это. В моем случае это случай отключения после отправки результата. Он отключается после отправки результата запроса и отключения.   -  person King    schedule 22.12.2011
comment
Это делается внутри каким-то образом, который я не могу контролировать на данный момент. И на самом деле в c++ libpq обрабатывает этот случай. Это мое предложение справиться с таким случаем обращения с ним. Спасибо. Продолжайте работать с Npgsql! Мы все хотели бы видеть лучшего поставщика. В настоящее время я вижу его как единственного поставщика .Net для postgresql.   -  person King    schedule 22.12.2011
comment
@FranciscoJunior В отредактированном примере это сработало, когда я не использовал его с одноразовыми предметами. Конечно, закрытие правильно, если не используется с одноразовым. Но одноразовая идеальна!   -  person King    schedule 22.12.2011
comment
Ты прав. Одноразовый - это выход. Я просто попросил вас закрыться и посмотреть, возникнет ли у вас проблема, чтобы попытаться воспроизвести проблему, поскольку использование конструкции просто вызывает метод dispose() читателя. Но теперь я понял проблему. Я попытаюсь воспроизвести это и посмотреть, как я могу это исправить.   -  person Francisco Junior    schedule 27.12.2011
comment
Не могли бы вы заполнить отчет об ошибке и добавить указатель на эту страницу для получения дополнительной информации? Это поможет нам отследить эту проблему. Просто проверьте: bugs.npgsql.org Заранее спасибо!   -  person Francisco Junior    schedule 27.12.2011
comment
Конечно ! Ваше здоровье. Продолжайте в том же духе !   -  person King    schedule 27.12.2011


Ответы (1)


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

Решение: Npgsql должен обрабатывать исключение внутри, которого еще нет.

person Community    schedule 26.12.2011