SqlDataReader.GetValue Зависает
Я запускаю процесс, встроенный в C# .Net 4.6.1, который обращается к базе данных SQL Server. Процесс выполняется в Windows Server 2012 R2 Standard. База данных SQL Server находится на другом сервере с SQL Server версии 11.0.6567.0
Процесс выполняет следующий код:
01 var readStatement = “select * from TableA order by ColumnX,ColumnY, ColumnZ offset 0 rows”; // TableA has 13 million rows
02 var readCommand = new SqlCommand(readStatement, myConnection) { CommandTimeout = 72000 };
03 var reader = readCommand.ExecuteReader();
04 while (reader.Read())
05 {
06 foreach (var columnName in columnNames)
07 {
08 Console.WriteLine(“Checkpoint 1”);
09 var value = reader[columnName];
10 Console.WriteLine(“Checkpoint 2”);
11 }
12 }
Этот процесс обычно завершается без проблем. Иногда он переходит в строку 09 (вызов SqlDataReader.GetValue) и никогда не возвращается. Я смог засвидетельствовать эту проблему при выполнении трассировки в базе данных. Процесс пошел на этот звонок примерно на 8 миллионов (из 13 миллионов), но так и не вернулся. Во время зависания трассировка базы данных показала "Пакет завершен", а затем "Выход из системы аудита". Я не могу воспроизвести проблему в отладчике, чтобы увидеть, как глубоко в SqlDataReader.GetValue процесс висит. Это не приводит к проблемам с памятью или другим ограничением ресурсов
Вот стек вызовов, где висит процесс:
System.Data.dll! SNINativeMethodWrapper.SNIReadSyncOverAsync Нормальный [Управляемый в собственный переход]
System.Data.dll! SNINativeMethodWrapper.SNIReadSyncOverAsync (System.Runtime.InteropServices.SafeHandle pConn, ref пакет System.IntPtr, int timeout)
System.Data.dll! System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync ()
System.Data.dll! System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket ()
System.Data.dll! System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer ()
System.Data.dll! System.Data.SqlClient.TdsParserStateObject.TryReadByteArray (буфер byte[], int смещение, int len, out int totalRead)
System.Data.dll! System.Data.SqlClient.TdsParserStateObject.TryReadDouble (из двойного значения)
System.Data.dll! System.Data.SqlClient.TdsParser.TryReadSqlValueInternal (значение System.Data.SqlClient.SqlBuffer, байт tdsType, длина int, System.Data.SqlClient.TdsParserStateObject stateObj)
System.Data.dll! System.Data.SqlClient.TdsParser.TryReadSqlValue (значение System.Data.SqlClient.SqlBuffer, System.Data.SqlClient.SqlMetaDataPriv md, длина int, состояние System.Data.SqlClient.TjObject. SqlClient.SqlCommandColumnEncryptionSetting columnEncryptionOverride, string columnName)
System.Data.dll! System.Data.SqlClient.SqlDataReader.TryReadColumnInternal (int i, bool readHeaderOnly)
System.Data.dll! System.Data.SqlClient.SqlDataReader.TryReadColumn (int i, bool setTimeout, bool allowPartiallyReadColumn)
System.Data.dll! System.Data.SqlClient.SqlDataReader.GetValueInternal (int i)
System.Data.dll! System.Data.SqlClient.SqlDataReader.GetValue (int i)