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

C#登录时System.InvalidOperationException连接未关闭报错求助

问题根因

你遇到的连接未关闭,当前状态为打开异常完全是代码里连接对象使用逻辑错误导致的,核心问题有3个:

  • 全局连接对象误用:你在窗体构造函数初始化了全局SqlConnection connection,但Login、LoginTeacher方法里明明用using创建了局部连接cnn,给SqlCommand绑定的却是全局的connection,全程没有用到局部连接,全局连接每次调用Open()后从未关闭,第二次调用就会触发异常。
  • 登录逻辑重复调用:登录按钮点击事件里先调用LoginTeacher,又调用Login,且Login方法校验通过后还会再次调用LoginTeacher,全局连接被多次尝试打开,直接触发报错。
  • 资源释放不规范:SqlDataReader用完未主动释放,using块会在作用域结束后自动释放连接,你在finally里重复写cnn.Close()属于多余操作。

修复步骤

  1. 删掉全局connection对象,所有数据库操作都使用using块创建的局部连接,避免连接复用导致的状态冲突
  2. 删掉重复的登录调用:登录按钮事件里只保留Login()调用,同时删掉Login方法内部的LoginTeacher()调用
  3. 给SqlDataReader也加上using块,自动释放读取器资源
  4. SqlCommand绑定using块里的局部连接,不用全局对象

修复后核心代码示例

public LoginForm()
{
    InitializeComponent();
    // 删掉全局connection初始化,不需要全局连接对象
}

#region Methods
public void LoginTeacher()
{
    // 只在Teacher角色需要单独校验的时候才调用这个方法,正常登录逻辑里不需要重复调用
    using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["CS"].ConnectionString))
    {
        try
        {
            // 绑定局部cnn连接,不是全局connection
            SqlCommand command = new SqlCommand("TeacherLogin", cnn);
            command.CommandType = CommandType.StoredProcedure;
            cnn.Open();
            command.Parameters.AddWithValue("@username", Txt_User.Text);
            command.Parameters.AddWithValue("@password", Txt_Pass.Text);
            // 给DataReader加using自动释放
            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                if (dataReader.Read())
                {
                    TeacherDash teacherDash = new TeacherDash();
                    this.Hide();
                    teacherDash.lblusertype.Text = dataReader[1] + " " + dataReader[2].ToString();
                    teacherDash.ShowDialog();
                    this.Close();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
        // 删掉多余的cnn.Close(),using会自动处理
    }
}

public void Login()
{
    using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["CS"].ConnectionString))
    {
        try
        {
            // 绑定局部cnn连接
            SqlCommand command = new SqlCommand("SP_USER_LOGIN", cnn);
            command.CommandType = CommandType.StoredProcedure;
            cnn.Open();
            command.Parameters.AddWithValue("@user", Txt_User.Text);
            command.Parameters.AddWithValue("@pass", Txt_Pass.Text);

            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                if (dataReader.Read())
                {
                    // 删掉重复的LoginTeacher()调用
                    string role = dataReader[10].ToString();
                    if (role.Equals("Admin"))
                    {
                        AdminDash adminDash = new AdminDash();
                        this.Hide();
                        adminDash.lblusertype.Text = dataReader[1] + " " + dataReader[2].ToString();
                        adminDash.ShowDialog();
                        this.Close();
                    }
                    else if (role.Equals("Teacher"))
                    {
                        // 如果Teacher需要额外校验再调用LoginTeacher,否则直接跳转
                        TeacherDash teacherDash = new TeacherDash();
                        this.Hide();
                        teacherDash.lblusertype.Text = dataReader[1] + " " + dataReader[2].ToString();
                        teacherDash.ShowDialog();
                        this.Close();
                    }
                    else if (role.Equals("Accounts"))
                    {
                        AccountsDash accountsDash = new AccountsDash();
                        this.Hide();
                        accountsDash.lblusertype.Text = dataReader[1] + " " + dataReader[2].ToString();
                        accountsDash.ShowDialog();
                        this.Close();
                    }
                    else if (role.Equals("Addmission"))
                    {
                        AdmissionDash admissionDash = new AdmissionDash();
                        this.Hide();
                        admissionDash.lblusertype.Text = dataReader[1] + " " + dataReader[2].ToString();
                        admissionDash.ShowDialog();
                        this.Close();
                    }
                }
                else if (string.IsNullOrWhiteSpace(Txt_User.Text) && string.IsNullOrWhiteSpace(Txt_Pass.Text))
                {
                    MessageBox.Show("用户名和密码均为空", "空字段", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else if (string.IsNullOrWhiteSpace(Txt_User.Text))
                {
                    MessageBox.Show("请输入用户名", "用户名为空", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else if (string.IsNullOrWhiteSpace(Txt_Pass.Text))
                {
                    MessageBox.Show("请输入密码", "密码为空", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("用户名或密码错误", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }
}
#endregion

private void Btn_Login_Click(object sender, EventArgs e)
{
    // 删掉重复的LoginTeacher调用,只保留Login
    Login();
}

private void pictureBox4_Click(object sender, EventArgs e)
{
    this.Close();
}

内容的提问来源于stack exchange,提问作者Noman ßaloch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 23:54:04