【问题标题】:Execution Timeout Expired when closing IDataReader关闭 IDataReader 时执行超时
【发布时间】:2018-01-31 20:28:11
【问题描述】:

我正在从 SQL Server 检索大量数据。一切正常,但是当我尝试在 using 语句中关闭 IDataReader

try
    {
      using (SqlConnection con = new SqlConnection(connString))
       {
         con.Open();
         using (SqlCommand command = new SqlCommand(sql_query, con))
         {
           command.CommandTimeout = 0;

           using (IDataReader rdr = new SqlCommand(sql_query, con).ExecuteReader(CommandBehavior.SequentialAccess))
            {
              dataTable = GetDataTableFromDataReader(rdr);
            }
             ....

我得到: 执行超时已过期。在操作完成之前超时时间已过或服务器没有响应。

使用 rdr = null 之类的东西会更好吗?或者还有其他更好的解决方案如何关闭 IDataReader?

【问题讨论】:

  • 我怀疑处理数据读取器会导致超时。您可以完全执行GetDataTableFromDataReader 吗?你调试了吗?
  • 你为什么要使用SequentialAccess?你读过巨大的二进制数据吗?这使得读取行不是一次,而是作为流,然后您可以使用GetBytes 部分读取二进制文件。
  • 这工作正常,但是当它离开最后一个大括号时会陷入异常。
  • 是的,MSDN 上建议使用 SequentialAccess,以防数据量巨大。不是二进制数据。
  • 不是庞大的数据,而是庞大的二进制数据。如果您只选择大量行,则不应使用SequentialAccess

标签: c# .net idatareader


【解决方案1】:

请注意,连接和命令都有超时设置。您无需在 using 块内手动关闭或处置。

您正在using 块中创建第二个SqlCommand,它没有设置超时。改为:

using (IDataReader rdr = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
    dataTable = GetDataTableFromDataReader(rdr);
}

【讨论】:

  • 我需要保留它,因为 SqlDataAdapter da = new SqlDataAdapter(command); if (showprogress) { Console.WriteLine("从 sql server 下载数据并推入 DataTable 对象"); } da.Fill(dataTable);
  • 我比较了您的解决方案,1e6 条记录需要 65200 毫秒。不使用以 rdr = null 结尾的语句需要 38630 毫秒。似乎它停留在关闭 IDataReader 上。
  • 只写是否正确:IDataReader rdr = new SqlCommand(sql_query, con).ExecuteReader(CommandBehavior.SequentialAccess);dataTable = GetDataTableFromDataReader(rdr); rdr = null;
  • 而不是 using 语句?
  • 您不必使用“使用”块。如果您不手动关闭和处置对象,不要忘记异常情况。在这种情况下,通常在 try-catch 之前声明一个对象并在“finally”块中释放(检查是否存在并已释放。你也可以去异步。这是基于表单的,但你会得到一个想法stackoverflow.com/questions/45950113/…
猜你喜欢
  • 2018-04-30
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 2012-04-18
相关资源
最近更新 更多