代码之家  ›  专栏  ›  技术社区  ›  StingyJack

导致“在sninativemethodwrapper.snipacketgetconnection(intptr数据包)处中止线程”的sqlclient调用

  •  5
  • StingyJack  · 技术社区  · 17 年前

    我真的很感激任何建议,无论多么简单或复杂,帮助我把这个问题孤立和解决。

    我有一些代码可以生成小报告文件。对于集合中的每个文件,都会执行一个存储过程来通过XML阅读器(它是一个非常大的结果集)获取数据。当我创造了这一切,并跨过它,一切都是好的。文件已生成,没有错误。

    此库通过远程处理调用,并通过IIS托管。当我部署编译的库并调用它时,它能够生成一些报告,但随后抛出一个线程中止异常。如果我将调试器附加到ASP工作进程,并单步执行代码,我就没有问题。

    鉴于这种失败是相当一致的,我寻找相似之处,发现失败发生在不同的报告上,但似乎发生在同一时间点。

    这让我觉得调试器重写的是一个超时设置,我对整个进程(而不是单个失败代码)做了一些粗略的计时,似乎在大约200秒后失败。web.config executiontimeout设置为600分钟(足够高)。此服务器应用程序的其他部分需要COM+事务(2分钟超时),但这不是其中之一。我不知道它会达到什么样的超时(大约是200秒)。

    SQL连接超时保留为默认值(连接成功打开),命令超时为300秒(执行命令只需12-15秒)。

    • 是否还有其他可能丢失的超时?

    我运行了SQL事件探查器,结果显示返回正确(所有语句和RPC都已完成-没有错误)。通过SSMS执行代码提供了完美的结果。

    使用Reflector,我深入研究了sninactiveMethodwRapper,它是一个非托管代码的包装器,我看不到它实际要做什么。我只能假设(可能是错误的)代码已经从SQL服务器接收到了TDS,包装器正在尝试获取与数据包相关联的连接,但它不能。

    • 有人知道这个包装应该做什么吗?
    • 是否有任何方法跟踪/调试此代码以找出导致失败的原因?

    我尝试使用不同的方法(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
    

    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 回复  |  直到 11 年前
        1
  •  1
  •   StingyJack    17 年前

    我相信我已经解决了这个问题。上面例子中的违规代码行是语句…

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

    这是对应用程序块(MS Enterprise Library)的调用,用于将事件记录到平面文件(在本例中)或事件日志中。

    在executeXmlReader()和XML文档中读卡器的实际使用之间,这个线程有时会发生严重故障,导致整个线程中止。我把电话线移到了 _xmlReader.Close() 它解决了这个问题。