Вызовы SqlClient, вызывающие «Поток был прерван в SNINativeMethodWrapper.SNIPacketGetConnection (пакет IntPtr)» - PullRequest
6 голосов
/ 08 января 2009

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

У меня есть немного кода, который генерирует небольшие файлы отчетов. Для каждого файла в коллекции выполняется хранимый процесс для получения данных через XML-ридер (это довольно большой набор результатов). Когда я все это создал и прошел через все, все хорошо. Файлы генерируются, ошибок нет.

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

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

Это привело меня к мысли, что это была установка тайм-аута, что отладчик переопределяет, я сделал некоторые грубые временные рамки всего процесса (не единственного фрагмента кода с ошибкой), и он, похоже, завершился ошибкой примерно через 200 секунд. Время выполнения web.config устанавливается на 600 минут (достаточно много). В этом серверном приложении есть и другие части, требующие транзакций COM + (время ожидания 2 минуты), но это не одна из них. Я в недоумении относительно того, какой тайм-аут может быть достигнут (около 200 секунд).

Тайм-аут соединения SQL остается по умолчанию (соединение открывается успешно), время ожидания команды составляет 300 секунд (для выполнения команды требуется всего 12-15).

  • Есть ли другой тайм-аут, который я мог бы пропустить?

Я запустил SQL-профилировщик, и он показывает, что результат возвращается правильно (все операторы и RPC выполнены - ошибок нет). Выполнение кода через SSMS дает отличные результаты.

Используя рефлектор, я углубился в SNINativeMethodWrapper и его оболочку для неуправляемого кода, и я не вижу, что он на самом деле пытается сделать. Я могу только предположить (возможно, ошибочно), что код получил TDS от сервера SQL, а оболочка пытается установить соединение, связанное с пакетом, и не может.

  • Кто-нибудь знает, что должен делать этот упаковщик?
  • Есть ли способ отследить / отладить этот код, чтобы выяснить причину сбоя?

Я пытался использовать разные методы (ExecScalar, DataAdapter), но все они используют ExecuteReader внутри.

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

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

Это код вызова, где генерируется исключение.

Private Function GetDataAsXmlDoc(ByVal cmd As SqlClient.SqlCommand) As XmlDocument

    Dim _xmlDoc As XmlDocument

    Using _connection As New SqlClient.SqlConnection(GetConnectionString())

        Logging.DebugEvent.Raise(Me.GetType.Namespace, Reflection.MethodBase.GetCurrentMethod().Name, _
                                 "No cached data found or used. Getting data for report from the database using SQL connection.")

        Dim _xmlReader As XmlReader
        'DataAdapter,ExecuteScalar, ExecuteXmlReader all use ExecuteReader internally and suffer the same problem.'
        'If you dont believe me, reflect it or look at one of the blowed up stack traces. '

        '_connection.ConnectionString += ";Pooling=false;"' 'This has no effect on the ThreadAbort.'
        cmd.Connection = _connection
        cmd.CommandTimeout = 300
        _connection.Open()

        Logging.DebugEvent.Log(String.Format("Connection opened, using packet size of {0}.", _connection.PacketSize))

        _xmlReader = cmd.ExecuteXmlReader() 'Thread aborts in here'

        Logging.DebugEvent.Raise(Me.GetType.Namespace, Reflection.MethodBase.GetCurrentMethod().Name, _
                                 "Report data recieved from database")

        _xmlDoc = New XmlDocument()
        _xmlDoc.Load(_xmlReader)

        _xmlReader.Close()

    End Using

  Return _xmlDoc

End Function

Stack

Exception String - System.Threading.ThreadAbortException: Thread was being aborted.
   at SNINativeMethodWrapper.SNIPacketGetConnection(IntPtr packet)
   at System.Data.SqlClient.TdsParserStateObject.ProcessSniPacket(IntPtr packet, UInt32 error)
   at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
   at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
   at System.Data.SqlClient.TdsParserStateObject.ReadByte()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteXmlReader()...

1 Ответ

2 голосов
/ 14 января 2009

Мне кажется, я решил проблему. Обидной строкой кода в приведенном выше примере было утверждение ...

 Logging.DebugEvent.Raise(Me.GetType.Namespace, Reflection.MethodBase.GetCurrentMethod().Name, _
                                 "Report data recieved from database")

Это вызов Application Block (корпоративной библиотеки MS) для записи событий в простые файлы (в данном случае) или журналы событий.

Этот, между ExecuteXMLReader () и фактическим использованием средства чтения в документе XML, иногда приводил к серьезным ошибкам, вызывая прерывание всего потока. Я переместил строку после _xmlReader.Close(), и она позаботилась о проблеме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...