この問題を切り分けて解決するために、どんなに単純か複雑かに関係なく、提案をいただければ幸いです。
小さなレポート ファイルを生成するコードが少しあります。コレクション内の各ファイルに対して、ストアド プロシージャが実行され、XML リーダー (かなり大きな結果セット) を介してデータが取得されます。私がこれらすべてを作成し、ステップスルーしたとき、すべてが順調です。ファイルが生成され、エラーはありません。
このライブラリはリモート経由で呼び出され、IIS 経由でホストされます。コンパイルされたライブラリをデプロイして呼び出すと、レポートの一部を生成できますが、スレッド中止例外がスローされます。デバッガーを asp ワーカー プロセスにアタッチし、コードをステップ実行しても、問題はありません。
この失敗はかなり一貫しているため、類似点を探したところ、異なるレポートで失敗が発生していることがわかりましたが、ほぼ同じ発生時点で発生しているようです。
これにより、デバッガーがオーバーライドしているのはタイムアウト設定であると考えるようになりました。プロセス全体の大まかなタイミング (失敗したコードの 1 つの部分ではありません) を行ったところ、約 200 秒後に失敗したようです。web.config の executionTimeout は 600 分 (十分な長さ) に設定されています。このサーバー アプリケーションには他にも COM+ トランザクション (2 分間のタイムアウト) を必要とする部分がありますが、これはその 1 つではありません。私は、それがヒットする可能性のあるタイムアウトについて途方に暮れています(約200秒のマークで)。
SQL 接続のタイムアウトはデフォルトのまま (接続は正常に開きます)、コマンドのタイムアウトは 300 秒です (コマンドの実行に 12 ~ 15 秒しかかかりません)。
- 欠落している可能性のある他のタイムアウトはありますか?
SQL プロファイラーを実行したところ、結果が正しく返されたことが示されました (すべてのステートメントと RPC が完了しました - エラーはありません)。SSMS 経由でコードを実行すると、完璧な結果が得られます。
リフレクターを使用して、SNINativeMethodWrapper を掘り下げました。これはアンマネージ コードのラッパーであり、実際に何をしようとしているのかわかりません。コードが 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()...