LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C#Winform窗体应用程序中查询数据库时报错问题分析

admin
2025年1月19日 14:42 本文热度 233
执行长时间任务查询数据库,那么可能会出现一个问题:在执行长时间任务的过程中,如果点击了进度条中的“取消”按钮,此时可以停止程序执行查询数据库的任务,但是如果再次执行该任务时,可能会报错:“连接未关闭,连接的当前状态为打开”。

下面以一个简单的示例来看看出现上面所述问题的原因所在。
首先,用access创建一个数据库文件database.mdb,并保存在C#项目的bin\debug文件夹中。创建一个数据表TestData,在数据表里设置一个自增字段、一个姓名字段,一个年龄字段。
仍然使用上一篇文章中所创建窗体和类,只把DataOperate.cs这个类修改一下,改成以下的代码,用于模拟耗时的数据库读取任务:
 
using System;
using System.ComponentModel;
using System.Data.OleDb;
using System.Data;
using System.IO;
using System.Threading;

namespace Test
{
    internal class DataOperate
    {
        private static String StrConn;
        private static OleDbConnection conn;
        private static OleDbCommand sc;

        public void operating(BackgroundWorker worker)
        {
            ConnectDatabase();
            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(1000);  //暂停1秒,模拟耗时的数据库操作
                operate("insert into TestData(姓名,年龄) values('全栈开发的码农',3)");
                worker.ReportProgress(i*100/10);
            }
        }
       
        private void ConnectDatabase()
        {
            //连接数据库
            StrConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Directory.GetCurrentDirectory() + @"\database.mdb; " + "Persist Security Info=True;Jet OLEDB:Database Password=123456";
            try
            {
                conn = new OleDbConnection(StrConn);
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private void operate(String strsql)//插入、删除、更新等数据库操作
        {
            conn.Open();
            sc = new OleDbCommand();
            sc.CommandText = strsql;
            sc.Connection = conn;
            Thread.Sleep(1000);  //暂停1秒,模拟耗时的数据库操作
            sc.ExecuteNonQuery();
            conn.Close();
        }

        public void close()  //关闭数据库连接
        {
            if (conn.State == ConnectionState.Open)
            {
                conn.Close();
                conn.Dispose();
            }
        }

    }
}
此时,点击主窗体中的“开始”按钮,开始执行任务,往数据库里的TestData数据表插入记录,程序运行正常。执行到一半的时候,点击进度条窗体中的“取消”按钮,此时任务被取消。此时,如果再次点击主窗体中的“开始”按钮,出现“连接未关闭”的报错。
经分析,问题出现在OleDbConnection对象conn上,在DataOperate.cs类中,把OleDbConnection对象conn定义成static静态对象,这对于一般的数据库操作是没有问题的,因为每一个数据库执行方法中都有conn.open()和conn.close(),数据连接可以正常打开和正常关闭,而当使用了Backgroundworker对象进行进度报告时,中途突然中断数据库查询操作,那么会导致conn.close()无法正常执行,使得连接依然处于打开状态,下一次尝试再次连接时就出现了“连接未关闭”的报错。
解决问题的最简单粗暴的方法就是把static删除,使conn成为一个普通的非静态变量即可。这是因为static对象在程序运行的全过程中只能有一个实例,第一次执行数据库操作时,它已经实例化,再次执行数据库操作时,也只能使用它,不能再次实例化,而它没有被正常关闭连接,所以再次尝试连接数据库时会出现“连接未关闭”的情况,而如果采用了非静态变量,那么就相当于给conn对象重新实例化,用一个全新的完全不同于此前的实例来操作数据库,这样就不会报错了。


阅读原文:原文链接


该文章在 2025/1/21 9:36:19 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved