You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#应用报错‘连接未关闭,当前状态为打开’的排查与解决

解决C#中"The connection was not closed. The connection's current state is open"错误

错误原因

你代码里用了全局的SqlConnection实例(cn),多个数据库操作方法共用同一个连接对象,就会出现状态冲突:比如某个方法打开连接后还没关闭,另一个方法又尝试对这个连接执行操作(比如再次调用Open()),直接触发该错误。另外部分方法(比如getTable)没有显式管理连接状态,依赖SqlDataAdapter.Fill的隐式处理,一旦全局连接处于打开状态,就会引发冲突。

修复方案

核心原则是每个数据库操作创建独立的局部连接对象,用using语句自动管理资源生命周期,同时解决代码里的SQL注入风险。以下是逐个方法的修复代码:

1. 修改getTable方法

public DataTable getTable(string query)
{
    DataTable table = new DataTable();
    // 局部连接对象,using自动释放资源、关闭连接
    using (SqlConnection cn = new SqlConnection(myConnection()))
    {
        using (SqlCommand cm = new SqlCommand(query, cn))
        {
            SqlDataAdapter adapter = new SqlDataAdapter(cm);
            adapter.Fill(table);
        }
    }
    return table;
}

2. 修改ExecuteQuery方法

public void ExecuteQuery(String sql)
{
    try
    {
        using (SqlConnection cn = new SqlConnection(myConnection()))
        {
            cn.Open();
            using (SqlCommand cm = new SqlCommand(sql, cn))
            {
                cm.ExecuteNonQuery();
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

说明:原来的代码如果在cn.Open()后抛出异常,cn.Close()不会执行,用using可以确保连接无论是否异常都会自动关闭。

3. 修改getPassword方法

重点修复SQL注入问题+连接管理:

public string getPassword(string username)
{
    string password = "";
    using (SqlConnection cn = new SqlConnection(myConnection()))
    {
        cn.Open();
        // 参数化查询,彻底避免SQL注入
        string query = "SELECT password FROM tbUser WHERE username = @Username";
        using (SqlCommand cm = new SqlCommand(query, cn))
        {
            cm.Parameters.AddWithValue("@Username", username);
            using (SqlDataReader dr = cm.ExecuteReader())
            {
                // 直接通过Read()返回值判断是否有数据
                if (dr.Read())
                {
                    password = dr["password"].ToString();
                }
            }
        }
    }
    return password;
}

4. 修改ExtractData方法

增加空值处理,避免ExecuteScalar返回null时引发异常:

public double ExtractData(string sql)
{
    using (SqlConnection cn = new SqlConnection(myConnection()))
    {
        cn.Open();
        using (SqlCommand cm = new SqlCommand(sql, cn))
        {
            object result = cm.ExecuteScalar();
            // 处理查询结果为空的情况
            if (result == null || result == DBNull.Value)
            {
                return 0; // 可根据业务需求调整默认值
            }
            // 安全转换为double
            return double.TryParse(result.ToString(), out double data) ? data : 0;
        }
    }
}

关键修复点总结

  • 移除全局的SqlConnection、SqlCommand、SqlDataReader实例,每个方法内部创建局部对象,避免状态冲突
  • 用using语句包裹所有实现IDisposable的数据库对象,确保资源自动释放、连接自动关闭,无需手动调用Close()
  • 替换字符串拼接SQL为参数化查询,彻底杜绝SQL注入风险
  • 增加空值和类型转换的异常处理,提升代码健壮性

内容的提问来源于stack exchange,提问作者ahmed benamara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:03:10