0

「不可能な動作」の状況に直面しており、何らかの形でデバッグする必要があります。

A と B の 2 つのスレッドがあります。スレッド B クラスには、次の 3 つの変数があります。

public class ThreadBClass() {
    private static bool shouldStop = false;
    private static objects shouldStopLock = new object();
    public static void SetShouldStop()
    {
        lock( shouldStopLock ) {
           shouldStop = true;
        } 
    }
    public void Run()
    {
        while( true ) {
            lock( shouldStopLock ) {
                if( shouldStop ) {
                   break;
                }
            }
            doStuff(); << this thing queries SQL Azure database
        }
    }
}

スレッドAにはこれがあります

var bClass = new threadBClass();
var controlledThread = new Thread( bClass.Run );

スレッド B はRun()、定期的に SQL Azure データベースにクエリを実行する無限ループで実行されます。

これら 2 つのスレッドが Windows Azure Web ロール内で実行され、ロールが停止されると、次のことが起こります。ロールOnStop()はスレッド A で実行され、次のことを行います。

ThreadBClass.SetShouldStop();
const int count = 20;
for( int i = 0; i < count; i++ ) {
   if( controlledThread.IsAlive ) {
       break;
   }
   Thread.Sleep( 1000 );
}

フラグが設定されているときにスレッド B がたまたまデータベースを照会していない場合、すべてが正常に終了します。しかし、40% の確率で SQL データベース クエリが失敗し、次の例外が発生します。

System.Data.SqlClient.SqlException
Timeout expired.  The timeout period elapsed prior to completion of
the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
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.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName)
at System.Data.SqlClient.SqlConnection.BeginTransaction(IsolationLevel iso, String transactionName)
//my code of Run() here

ThreadState各スレッドの を出力してみました。スレッド B の状態はRunningであるため、中断されたわけではありません。

したがって、私にとって全体的な状況は正気ではないように見えます.1つのスレッドがしばらくの間ロックを取得し、次に別のスレッドをポーリングし、IsAliveその時点で別のスレッドでSQLクエリがタイムアウトします。そして、これは時々再現可能です

これをデバッグするにはどうすればよいですか? イベント、グローバル変数、.NET ランタイムが公開し、実際に何が起こっているかを調べるために使用できるその他のものはありますか?

4

0 に答える 0