6

この問題を切り分けて解決するために、どんなに単純か複雑かに関係なく、提案をいただければ幸いです。

小さなレポート ファイルを生成するコードが少しあります。コレクション内の各ファイルに対して、ストアド プロシージャが実行され、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()...
4

1 に答える 1

2

私は問題を解決したと信じています。上記の例の問題のあるコード行は、次のステートメントでした...

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

これは、イベントをフラット ファイル (この場合) またはイベント ログに記録するためのアプリケーション ブロック (MS エンタープライズ ライブラリ) への呼び出しです。

これは、ExecuteXMLReader() と XML ドキュメント内のリーダーの実際の使用の間で、時々激しく失敗し、スレッド全体が中止されました。行を後に移動し_xmlReader.Close()、問題を処理しました。

于 2009-01-14T14:26:19.290 に答える