【问题标题】:how to close connection/datareader when using SqlDataSource or ObjectDataSource使用 SqlDataSource 或 ObjectDataSource 时如何关闭连接/数据读取器
【发布时间】:2008-10-20 18:40:51
【问题描述】:

在 beta 测试期间,我们发现了连接池错误消息。因此,我一直在浏览代码并关闭未关闭的 SqlDataReader 对象。我需要知道的是如何关闭在 SqlDataSource 或 ObjectDataSource 标记的 SelectStatement 属性中指定的数据读取器(或者是否需要关闭)。不处理会不会有连接泄漏?

提前致谢!

【问题讨论】:

    标签: asp.net ado.net connection-pooling


    【解决方案1】:

    我倾向于使用“using”关键字,尤其是在处理打开和关闭与数据库的连接时。 “使用”是 Dispose 模式的快捷方式 - here 是指向 MSDN 文章的链接,here 是指向带有概述的有用博客条目的链接。

    【讨论】:

    • 这里也一样。我很惊讶有多少开发人员编写的代码不使用“using”关键字来自动处理对象(尤其是在使用数据读取器之类的东西时)。
    【解决方案2】:

    要提高 Close()/Dispose() 的性能,请考虑在释放或关闭读取器之前对关联的命令对象调用 Cancel(),尤其是当您没有到达记录集的末尾时。

    例如:

                using (var cmd = ... ))
                {
                    using (var reader = (DbDataReader) cmd.ExecuteReader())
                    {
                        try
                        {
                            ConsumeData(reader); // may throw
                        }
                        catch(Exception)
                        {
                            cmd.Cancel();
                            throw;
                        }
                    }
                }
    

    【讨论】:

      【解决方案3】:

      我的理解是,有了SqlDataSource,连接管理就替你做了,你什么都不怕。

      ObjectDataSource 首先不直接与数据库对话,因此它是安全的——只要底层对象正确执行其连接和读取器管理。

      正如其他人所提到的,Close()using 是您与 ObjectDataSource 一起使用的课程的朋友。

      我的预感是,如果您有效地清理了代码库,您可能已经根除问题。

      【讨论】:

        【解决方案4】:

        我们在生产环境中遇到了同样的问题。

        解决了这个问题。首先的问题是,我的代码中根本没有 using 语句。 (它是几年前构建的,知识较少)。

        然后我尝试将 SqlDataSource 放在 using 子句中。但这也无济于事。

        这里的诀窍是,就像 tvanfosson 和 Mischa 建议的那样,将读者置于 using 子句中。这是实际关闭连接的对象。

        在中等负载下,连接数减少到最小池大小 10。

        【讨论】:

          【解决方案5】:

          调用 .Dispose() 应该处理清理并释放任何持有的资源,但 .Close() method should be getting called as well when an object is done reading from the reader

          【讨论】:

          • 您不需要同时调用 Dispose() 和 Close()。 Dispose() 只是调用 Close()。您可以查看 DbDataReader 的源代码来验证这一点。
          【解决方案6】:

          我相信 SqlDataSource 会处理它自己的连接/阅读器问题,所以不用担心。至于您的手动连接,我发现这种模式在过去很有用:

             using (SqlConnection connection = new SqlConnection(connectionString))
             {
                try
                {
                   SqlCommand command = connection.CreateCommand();
                   command.CommandText = ...
          
                   connection.Open();
                   using (SqlDataReader reader = command.ExecuteReader())
                   {
                      do
                      {
                         while (reader.Read())
                         {
                            ... handle each row ...
                         }
                      } while (reader.NextResult());
                   }
                }
                catch (Exception ex)
                {
                    ... error handling ...
                }
                finally
                {
                   if (connection != null && connection.State == ConnectionState.Open)
                   {
                      connection.Close();
                   }
                }
            }
          

          【讨论】:

            【解决方案7】:

            我同意,对于 ObjectDataSource,关闭应由其 Select 方法处理。我的 ObjectDataSource Select 方法返回一个 SqlDataReader。我担心的是......将 SqlDataReader 返回到 UI 后关闭时是否会变得无用。例如请参阅以下示例代码。我没有尝试过,也不想在这个开发阶段这样做。

            SqlDataReader MySelectMethod(){
               SqlDataReader dr = null;
               try{
                  dr = DBObject.GetDataReader();
                  return dr;
               }
               finally{
                  dr.Close();
               }
            }
            

            感谢迄今为止收到的所有意见!

            ...........

            我的理解是 SqlDataSource,连接管理 为您执行,并且您有 没什么好怕的。

            ObjectDataSource 不与 数据库直接放在首位, 所以它是安全的——只要 底层对象执行其 连接和读卡器管理 正确。

            正如其他人提到的,Close() 和 使用是你上课的朋友 您与 ObjectDataSource 一起使用

            .

            【讨论】:

            • 这行不通。由于在finally块中,所以在return发生时会执行close(代码退出try块并最终执行)。
            猜你喜欢
            • 1970-01-01
            • 2012-01-21
            • 1970-01-01
            • 2010-11-15
            • 2010-09-08
            • 1970-01-01
            • 2015-01-15
            • 1970-01-01
            • 2017-07-19
            相关资源
            最近更新 更多