本文介绍了ADO.Net SQLCommand.ExecuteReader()减慢或挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境:



应用程序(为.Net 4用C#编写)最多具有10个线程,每个线程都在自己的AppDomain中运行。每个线程都使用一个ADO.Net DataReader,它从SQL-Server 2008上的存储过程中获取结果。一个线程也可以使用ADO.Net来执行写操作(批量插入)。一切都在本地计算机上运行。



问题1:



有时(大约每运行30次)执行一次线程急剧减速。当DataReader获取存储过程结果-SqlCommand.ExecuteReader()时,就会发生这种情况。通常,读取操作会在10秒内执行。当它变慢时,它会在10-20分钟内执行。 SQLProfiler显示正在查询数据,尽管速度非常慢。



减速的调用堆栈(请注意,没有例外):

 在SNIReadSync(SNI_Conn *,SNI_Packet **,Int32)
在SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn,IntPtr& packet,Int32超时)
在System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult,TdsParserStateObject stateObj)
在System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
在System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
在System.Data.SqlClient.TdsParserStateObject.ReadByteArray(Byte [] buff,Int32偏移量,Int32 len)
在System.Data.SqlClient.TdsParserStateObject.ReadString(Int32长度)
在系统。 Data.SqlClient.TdsParser.ReadSqlStringValue(SqlBuffer值,字节类型,Int32长度,编码编码,布尔值isPlp,TdsParserStateObject stateObj)
位于System.Data.SqlClient.TdsParser.ReadSqlValue (SqlBuffer值,SqlMetaDataPriv md,Int32长度,TdsParserStateObject stateObj)
在System.Data.SqlClient.SqlDataReader.ReadColumnData()
在System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
在System.Data.SqlClient.SqlDataReader.ReadColumn(Int32 i,布尔setTimeout)在System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
在System.Data.SqlClient.SqlDataReader.GetValue (Int32 i)System.Data.SqlClient.SqlDataReader.get_Item(String name)
在****。Core.TableDataImporter.ImportDataFromExcel(Int32 tableId,ExcelEntityLocation location,Boolean& updateResult)in…

问题#2:



而不是减慢线程的挂起速度。



Callstack:

 在SNIReadSync(SNI_Conn *,SNI_Packet **,Int32)
在SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn,IntPtr& packet,Int32超时)在System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult) asyncResult,TdsParserStateObject stateObj)
在System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
在System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
在System.Data.SqlClient.TdsParserStateObject。 System.Data.SqlClient.TdsParser.Run上的ReadByte()
(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)
在System.Data.SqlClient.SqlDataReader.ConsumeMetaData() System.Data.SqlClient.SqlDataReader.get_MetaData()的b $ b System.Dat的b $ b a.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString)
在System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,布尔异步)
at .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) )System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior,String method)中的
System.Data.SqlClient.SqlCommand.ExecuteReader()

调用栈是使用后台线程中的调试工具获取的。



SNIReadSync是一种在网络级别上运行并可以在网络上传输数据包的机制。我们已经在本地计算机上重现了此问题,从等式中消除了网络问题。



我们正在寻找这种减速/挂断的任何输入,解决方案或解决方法。现在,我们计划检测到速度下降,然后重新运行该操作。



我将按要求为该方法添加简化代码:

  public void ImportDataFromExcel()
{
try
{
var_сonnectionBuilk= ...; //单例连接(在应用程序级别)
var spName = ...; //存储过程名称

varсonnectionToRead= new SqlConnection(connectionStirng);
сonnectionToRead.Open();

var sqlCommand = new SqlCommand(spName);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.Add(param1Name,SqlDbType.Int).Value = ...;
sqlCommand.Parameters.Add(param2Name,SqlDbType.Int).Value = ...;
sqlCommand.Parameters.Add(param2Name,SqlDbType.Int).Value = ...;

sqlCommand.Connection =сonnectionToRead;
sqlCommand.CommandTimeout =超时; // 120秒

使用(var dataReader = sqlCommand.ExecuteReader())
{
dataReader.Read();
.....
int pos1 = dataReader.GetOrdinal(columnName1);
int pos2 = dataReader.GetOrdinal(columnName2);
int pos3 = dataReader.GetOrdinal(columnName3);
int pos4 = dataReader.GetOrdinal(columnName4);
.....

//从sqldatareader读取数据
int val1 = dataReader.GetInt32(pos1);
int val2 = dataReader.GetInt32(pos2);
int val3 = dataReader.GetInt32(pos3);
var val4 = dataReader.GetDateTime(pos4);
.....

//将读取的数据附加到bulkTable
bulkTable.AddCellValue(val1,val2,val3,val4); // bulkTable包装DataTable,并在其中附加DataRow。

if(bulkTable.DataTable.Rows> MaxRowsCount)
{
使用(var bulkCopy = new SqlBulkCopy(_сonnectionBuilk))
{
bulkCopy。 DestinationTableName = _fullTableName;
bulkCopy.WriteToServer(bulkTable.DataTable);
}

var sqlCommandTransfer = new SqlCommand(spName);
sqlCommandTransfer.CommandType = CommandType.StoredProcedure;
sqlCommandTransfer.Parameters.Add(param1Name,SqlDbType.Int).Value = ...;
sqlCommandTransfer.Connection =_сonnectionBuilk;
....
sqlCommandTransfer.ExecuteNonQuery(); //将数据从临时批量表传输到原始表
}
}
}
最后
{
bulkTable.Dispose();
сonnectionToRead.Close();
}
}


解决方案

我们几个月来一直在尝试调试类似的问题,直到今天终于找到了它。



我们有一个查询被藏在缓存中(没有calliong ToList / ToArray / etc。)。该查询实际上与后来被清除的连接相关,我们从 ReadSni (下面包括完整堆栈)中获得了100%的CPU阻塞。 p>

我怀疑在查询被更改为使用Linq之前已编写了缓存代码(并用来代替返回 List< T> ,但仍强制转换为 IEumberable ),因此在有人使数据访问惰性时引入了它。



  OS线程ID:0x20b8(27)
子SP IP呼叫站点
16edd0fc 6184267e System.Data.SqlClient.TdsParserStateObject.ReadSni(System.Data.Common.DbAsyncResult,System.Data.SqlClient。 TdsParserStateObject)
16edd134 61842624 System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
16edd144 618446af System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
16edd150 61c583d0 System.Data.SqlClient.TdsParserStateObject。 CleanWire()
16edd15c 61d1beb9 System.Data.SqlClient.TdsParser.Deactivate(Boolean)
16edd174 6184995f System.Data.SqlClient.SqlInternalConnectionTds.InternalDeactivate()
16edd180 61849640 System.Data.SqlClient。 SqlInternalConnection.Deactivate()
16edd1b0 61849587 System.Data.ProviderBase.DbConnectionInternal.DeactivateConnection()
16edd1e4 61849405 System.Data.ProviderBase.DbConnectionPoo l.DeactivateObject(System.Data.ProviderBase.DbConnectionInternal)
16edd224 61849384 System.Data.ProviderBase.DbConnectionPool.PutObject(System.Data.ProviderBase.DbConnectionInternal,System.Object)
16edd26c 6184920c System.Data。 ProviderBase.DbConnectionInternal.CloseConnection(System.Data.Common.DbConnection,System.Data.ProviderBase.DbConnectionFactory)
16edd2ac 618490f7 System.Data.SqlClient.SqlInternalConnection.CloseConnection(System.Data.Common.DbConnection,System.Data。 ProviderBase.DbConnectionFactory)
16edd2c4 618393bf System.Data.SqlClient.SqlConnection.Close()
16edd304 11238f0a NHibernate.Connection.ConnectionProvider.CloseConnection(System.Data.IDbConnection)
16edd340 11238eae NHibernate.Connection .DriverConnectionProvider.CloseConnection(System.Data.IDbConnection)
16edd34c 11aceb42 NHibernate.AdoNet.ConnectionManager.CloseConnection()
16edd358 11aceb02 NHibernate.AdoNet.ConnectionManager.AggressiveRelease()
16edd364 11acf783 NHibebe rnate.AdoNet.ConnectionManager.AfterTransaction()
16edd370 11acf6d1 NHibernate.Impl.SessionImpl.AfterTransactionCompletion(Boolean,NHibernate.ITransaction)
16edd3ec 11acf5de NHibernate.AdoNet.ConnectionManager.AfterNonTransactionalQuery(eded3 $ b) 11acf539 NHibernate.Impl.AbstractSessionImpl.AfterOperation(布尔)
16edd474 130311e4 NHibernate.Impl.SessionImpl.List(NHibernate.IQueryExpression,NHibernate.Engine.QueryParameters,System.Collections.IList)
16ede51c 13031071 NHibernateImpl .AbstractSessionImpl.List(NHibernate.IQueryExpression,NHibernate.Engine.QueryParameters)
16ede538 13030b68 NHibernate.Impl.ExpressionQueryImpl.List()
16ede568 13030a47 NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NHibernate.Linq.NhL NHibernate.IQuery,NHibernate.Linq.NhLinqExpression)
16ede59c 11d4c163 NHibernate.Linq.DefaultQueryProvider.Execute(System.Linq.Expressions.Expression)
16ede5b0 11d4c108 NHibernate.Linq.DefaultQueryProvi der.Execute [[System .__ Canon,mscorlib]](System.Linq.Expressions.Expression)
16ede5c4 11d4c0a6 Remotion.Linq.QueryableBase`1 [[System .__ Canon,mscorlib]]。GetEnumerator()
16ede5d4 61022108 System.Linq.Enumerable + WhereEnumerableIterator`1 [[System .__ Canon,mscorlib]]。MoveNext()***警告:无法验证System.Core.ni.dll的校验和
***错误:模块加载已完成,但无法为System.Core.ni.dll

16ede5e4 610166ea System.Linq.Buffer`1 [[System .__ Canon,mscorlib]] .. ctor(System。 Collections.Generic.IEnumerable`1< System .__ Canon>)
16ede620 6122e171 System.Linq.OrderedEnumerable`1 +< GetEnumerator> d__0 [[System .__ Canon,mscorlib] .MoveNext()
16ede63c 79b39758 System.Collections.Generic.List`1 [[System .__ Canon,mscorlib]] .. ctor(System.Collections.Generic.IEnumerable`1< System .__ Canon>)***警告:无法验证mscorlib的校验和。 ni.dll
***错误:模块加载已完成,但无法为mscorli加载符号b.ni.dll

16ede66c 61021acf System.Linq.Enumerable.ToList [[System .__ Canon,mscorlib]](System.Collections.Generic.IEnumerable`1< System .__ Canon>)


Environment:

Application (written in C# for .Net 4) has up to 10 threads, each thread runs in its own AppDomain. Each thread uses a ADO.Net DataReader that gets the results from the stored procedure on SQL-Server 2008. Also a thread can use ADO.Net to perform a write operation (Bulk Insert). Everything runs on the local machine.

Problem #1:

Occasionally (approximately each 30th run) execution of a thread slows down drastically. That happens when DataReader gets the stored procedure results - SqlCommand.ExecuteReader(). Usually read operation executes in 10 seconds. When it slows down, it executes in 10-20 minutes. SQLProfiler shows that data is being queried, though very slowly.

Callstack of the slowdown (please note that there are no exceptions):

at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32 )
   at SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn, IntPtr& packet, Int32 timeout)
   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.ReadByteArray(Byte[] buff, Int32 offset, Int32 len)
   at System.Data.SqlClient.TdsParserStateObject.ReadString(Int32 length)
   at System.Data.SqlClient.TdsParser.ReadSqlStringValue(SqlBuffer value, Byte type, Int32 length, Encoding encoding, Boolean isPlp, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.ReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ReadColumnData()
   at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
   at System.Data.SqlClient.SqlDataReader.ReadColumn(Int32 i, Boolean setTimeout)
   at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
   at System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)
   at System.Data.SqlClient.SqlDataReader.get_Item(String name)
   at ****.Core.TableDataImporter.ImportDataFromExcel(Int32 tableId, ExcelEntityLocation location, Boolean& updateResult) in …

Problem #2:

Instead of a slowing down a thread can hang.

Callstack:

at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32 )
   at SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn, IntPtr& packet, Int32 timeout)
   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.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader()

Callstacks were acquired using debug tools in the background thread. No exceptions do happen, either a slowdown or hanging up.

SNIReadSync is a mechanism that works on the network level and works with transmitting packets across the network. We have reproduced this problem on local machine, removing network problems from the equation.

We are looking for any input and solutions or workarounds for this slowdowns/hang ups. For now we a planning to detect the slowdown an rerun the operation. Thanks in advance.

I'm appending simplified code for the method as requested:

  public void ImportDataFromExcel()
    {            
        try
        {                
            var _сonnectionBuilk = ... ; // singleton connection (at the app level)
            var spName = ... ; // stored procedure name

        var сonnectionToRead = new SqlConnection(connectionStirng);
        сonnectionToRead.Open();

        var sqlCommand = new SqlCommand(spName);
        sqlCommand.CommandType = CommandType.StoredProcedure; 
        sqlCommand.Parameters.Add(param1Name, SqlDbType.Int).Value = ...;
        sqlCommand.Parameters.Add(param2Name, SqlDbType.Int).Value = ...;
        sqlCommand.Parameters.Add(param2Name, SqlDbType.Int).Value = ...;

        sqlCommand.Connection = сonnectionToRead;            
        sqlCommand.CommandTimeout = timeout; // 120 sec

        using (var dataReader = sqlCommand.ExecuteReader())
        {
                dataReader.Read();
            .....
            int pos1 = dataReader.GetOrdinal(columnName1);
            int pos2 = dataReader.GetOrdinal(columnName2);
            int pos3 = dataReader.GetOrdinal(columnName3);
            int pos4 = dataReader.GetOrdinal(columnName4);
                .....                    

            // reading data from sqldatareader
            int val1 = dataReader.GetInt32(pos1);
            int val2 = dataReader.GetInt32(pos2);
            int val3 = dataReader.GetInt32(pos3);
            var val4 = dataReader.GetDateTime(pos4);
            .....

            // append read data into bulkTable
            bulkTable.AddCellValue(val1, val2, val3, val4);  // bulkTable wraps DataTable, and appends DataRow inside. 

            if(bulkTable.DataTable.Rows > MaxRowsCount)
            {
                using (var bulkCopy = new SqlBulkCopy(_сonnectionBuilk))
                {
                    bulkCopy.DestinationTableName = _fullTableName;
                    bulkCopy.WriteToServer(bulkTable.DataTable);
                }

                var sqlCommandTransfer = new SqlCommand(spName);
                sqlCommandTransfer.CommandType = CommandType.StoredProcedure; 
                sqlCommandTransfer.Parameters.Add(param1Name, SqlDbType.Int).Value = ...;
                sqlCommandTransfer.Connection = _сonnectionBuilk;
                ....
                sqlCommandTransfer.ExecuteNonQuery(); // transfering data from temp bulk table into original table
            }
        }
    }
    finally
    {
        bulkTable.Dispose();
        сonnectionToRead.Close();
    }
}
解决方案

We've been trying to debug a similar issue for months, and finally tracked it down today...

We had a query that was being stashed into the cache (without calliong ToList/ToArray/etc. on it). The query was effectively tied to a connection that had since been cleaned up, and we got what appeared to be 100% CPU blocking from ReadSni (full stack included below).

I suspect the caching code was written before the query was changed over to use Linq (and used to instead return a List<T>, but still cast as IEumberable) so it was introduced when someone made the data access "lazy".

I can't explain why it only happened every few days in production; either the caching isn't being used a lot, or the connection had to be in a certain state for it to fail in this way.

OS Thread Id: 0x20b8 (27)
Child SP IP       Call Site
16edd0fc 6184267e System.Data.SqlClient.TdsParserStateObject.ReadSni(System.Data.Common.DbAsyncResult, System.Data.SqlClient.TdsParserStateObject)
16edd134 61842624 System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
16edd144 618446af System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
16edd150 61c583d0 System.Data.SqlClient.TdsParserStateObject.CleanWire()
16edd15c 61d1beb9 System.Data.SqlClient.TdsParser.Deactivate(Boolean)
16edd174 6184995f System.Data.SqlClient.SqlInternalConnectionTds.InternalDeactivate()
16edd180 61849640 System.Data.SqlClient.SqlInternalConnection.Deactivate()
16edd1b0 61849587 System.Data.ProviderBase.DbConnectionInternal.DeactivateConnection()
16edd1e4 61849405 System.Data.ProviderBase.DbConnectionPool.DeactivateObject(System.Data.ProviderBase.DbConnectionInternal)
16edd224 61849384 System.Data.ProviderBase.DbConnectionPool.PutObject(System.Data.ProviderBase.DbConnectionInternal, System.Object)
16edd26c 6184920c System.Data.ProviderBase.DbConnectionInternal.CloseConnection(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory)
16edd2ac 618490f7 System.Data.SqlClient.SqlInternalConnection.CloseConnection(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory)
16edd2c4 618393bf System.Data.SqlClient.SqlConnection.Close()
16edd304 11238f0a NHibernate.Connection.ConnectionProvider.CloseConnection(System.Data.IDbConnection)
16edd340 11238eae NHibernate.Connection.DriverConnectionProvider.CloseConnection(System.Data.IDbConnection)
16edd34c 11aceb42 NHibernate.AdoNet.ConnectionManager.CloseConnection()
16edd358 11aceb02 NHibernate.AdoNet.ConnectionManager.AggressiveRelease()
16edd364 11acf783 NHibernate.AdoNet.ConnectionManager.AfterTransaction()
16edd370 11acf6d1 NHibernate.Impl.SessionImpl.AfterTransactionCompletion(Boolean, NHibernate.ITransaction)
16edd3ec 11acf5de NHibernate.AdoNet.ConnectionManager.AfterNonTransactionalQuery(Boolean)
16edd3fc 11acf539 NHibernate.Impl.AbstractSessionImpl.AfterOperation(Boolean)
16edd474 130311e4 NHibernate.Impl.SessionImpl.List(NHibernate.IQueryExpression, NHibernate.Engine.QueryParameters, System.Collections.IList)
16ede51c 13031071 NHibernate.Impl.AbstractSessionImpl.List(NHibernate.IQueryExpression, NHibernate.Engine.QueryParameters)
16ede538 13030b68 NHibernate.Impl.ExpressionQueryImpl.List()
16ede568 13030a47 NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NHibernate.Linq.NhLinqExpression, NHibernate.IQuery, NHibernate.Linq.NhLinqExpression)
16ede59c 11d4c163 NHibernate.Linq.DefaultQueryProvider.Execute(System.Linq.Expressions.Expression)
16ede5b0 11d4c108 NHibernate.Linq.DefaultQueryProvider.Execute[[System.__Canon, mscorlib]](System.Linq.Expressions.Expression)
16ede5c4 11d4c0a6 Remotion.Linq.QueryableBase`1[[System.__Canon, mscorlib]].GetEnumerator()
16ede5d4 61022108 System.Linq.Enumerable+WhereEnumerableIterator`1[[System.__Canon, mscorlib]].MoveNext()*** WARNING: Unable to verify checksum for System.Core.ni.dll
*** ERROR: Module load completed but symbols could not be loaded for System.Core.ni.dll

16ede5e4 610166ea System.Linq.Buffer`1[[System.__Canon, mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1<System.__Canon>)
16ede620 6122e171 System.Linq.OrderedEnumerable`1+<GetEnumerator>d__0[[System.__Canon, mscorlib]].MoveNext()
16ede63c 79b39758 System.Collections.Generic.List`1[[System.__Canon, mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1<System.__Canon>)*** WARNING: Unable to verify checksum for mscorlib.ni.dll
*** ERROR: Module load completed but symbols could not be loaded for mscorlib.ni.dll

16ede66c 61021acf System.Linq.Enumerable.ToList[[System.__Canon, mscorlib]](System.Collections.Generic.IEnumerable`1<System.__Canon>)

这篇关于ADO.Net SQLCommand.ExecuteReader()减慢或挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 12:16