抛出异常时,DataAdapter.Fill()是否会关闭其连接?

时间:2010-03-18 19:41:22

标签: .net ado.net .net-1.1 sqlconnection resource-leak

我在遗留应用程序中使用ADO.NET(.NET 1.1)。我知道DataAdapter.Fill()会在连接到DataAdapter之前手动打开连接时打开和关闭连接。

我的问题:如果.Fill()导致异常,是否也会关闭连接?(由于无法访问SQL Server,或其他)。它是否泄漏连接,或者它是否具有内置的Finally子句以确保连接正在关闭。

代码示例:

Dim cmd As New SqlCommand
Dim da As New SqlDataAdapter
Dim ds As New DataSet
cmd.Connection = New SqlConnection(strConnection)
cmd.CommandText = strSQL
da.SelectCommand = cmd
da.Fill(ds)

2 个答案:

答案 0 :(得分:21)

如果在调用Fill()方法之前连接已打开,则不会,DataAdapter不会关闭连接。

但是,如果您没有显式打开连接,而是让DataAdapter在Fill()命令中打开和关闭连接,那么连接将在出错时关闭。

这可以从多个文档来源暗示,包括这一个:Data Access Strategies Using ADO.NET and SQL

此外,这可以通过编写一个错误输出然后检查连接状态的例程在代码中演示。

来自Windows窗体应用程序的此代码证明了这一点。第一个消息框将显示“打开”,第二个消息框将显示“已关闭”。

              string connString = "";
        private void Form1_Load(object sender, EventArgs e)
        {
            connString = Properties.Settings.Default.EventLoggingConnectionString;
            ExplicitlyOpenConnection();
            LetDataAdapterHandleIt();
        }

        private void ExplicitlyOpenConnection()
        {
            System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(connString);
            System.Data.DataSet ds = new DataSet();
            System.Data.SqlClient.SqlDataAdapter ad = new System.Data.SqlClient.SqlDataAdapter("Select bogusdata from nonexistenttable", cn);

            cn.Open();
            try
            {
                ad.Fill(ds);
            }
            catch (Exception ex)
            {

            }

            MessageBox.Show(cn.State.ToString());
            cn.Close();
        }
        private void LetDataAdapterHandleIt()
        {
            System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(connString);
            System.Data.DataSet ds = new DataSet();
            System.Data.SqlClient.SqlDataAdapter ad = new System.Data.SqlClient.SqlDataAdapter("Select bogusdata from nonexistenttable", cn);

            try
            {
                ad.Fill(ds);
            }
            catch (Exception ex)
            {

            }
            MessageBox.Show(cn.State.ToString());
        }

答案 1 :(得分:1)

关闭连接。此示例工作并输出“ARealTable”的ID

            using (SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=database;user id=sa; password=password;"))
            {
                conn.Open();

                try
                {
                    SqlDataAdapter adap = new SqlDataAdapter("SELECT * FROM NotATable", conn); 
                    /* Exception thrown next */
                    adap.Fill(new DataSet("test"));
                }
                catch (Exception) { }

                using (SqlCommand cmd = new SqlCommand("SELECT TOP 1 Id FROM ARealTable", conn))
                {
                    string result = Convert.ToString(cmd.ExecuteScalar());
                    Console.WriteLine(result);
                }
                Console.ReadKey();

修改

如果您事先打开连接(在IDbConnection对象上调用Open),IDataAdapter将不会关闭它。但是,如果您允许IDataAdapter完全管理连接,它将被关闭。