Как я могу отлаживать таймаут в SQL-запросе, вызванном действием в другом потоке?

Я столкнулся с ситуацией «невозможного поведения», и мне нужно как-то отладить ее.

У меня есть два потока: A и B. Класс Thread B имеет эти три переменные:

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
        }
    }
}

Тема А имеет это

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

thread B запускает Run() с бесконечным циклом, периодически запрашивающим базу данных SQL Azure.

Теперь эти два потока выполняются внутри веб-роли Windows Azure, и когда роль останавливается, происходит следующее. Роль 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

Я попытался вывести <thread> ThreadState каждого потока. Состояние Thread B Running , поэтому оно определенно не прервано.

Итак, вся ситуация для меня выглядит безумной - один поток некоторое время приобретает блокировку, а затем опросает другой поток для IsAlive и точно в это время SQL-запрос истекает в другом потоке. И это воспроизводимо раз в то время .

Как мне отладить это? Есть ли какие-либо события, глобальные переменные, что бы они ни показывали в среде выполнения .NET, и что я мог бы использовать, чтобы найти то, что на самом деле происходит?

0
nl ja de
@Marc Gravell: Azure runtime вызывает OnStop() как часть намного большей последовательности «stop».
добавлено автор sharptooth, источник
@Marc Gravell: Итак, вы предполагаете, что проблема возникает вне программы. Ну, это имеет смысл. Не могли бы вы придумать минималистический ответ из вашего первого комментария?
добавлено автор sharptooth, источник
Что инициирует «роль прекращается»? Мне кажется, что это не связано с блокировкой/проверкой, но вместо этого связано с некоторыми другими вещами, которые происходят; возможно, сама подсистема отключает внешние подключения, потому что он знает, что роль закрывается . Установка значения внутри блокировки не приведет к ошибке TDS. Вещи, которые могут вызвать ошибку TDS, включают в себя: сервер базы данных занят; сервер базы данных закрывается; отключение сетевого соединения.
добавлено автор Marc Gravell, источник
да, я подумал; но недостаток: ошибка, которую вы видите, имеет ничего, что делать с вашей блокировкой/bool; это ошибка , потому что она закрывается .
добавлено автор Marc Gravell, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot