C#定时读取数据库,要么就出错,要么就是一闪一闪的很快

.Net技术 码拜 8年前 (2016-02-26) 1478次浏览
本人正在做一个从数据库实时读取数据显示到datagridview中,但是就是一直出现问题,本人是用定时器来定时读取数据库并且显示数据的,,本人想问一下下应该怎么改代码,可以解决这个问题,主要是希望不要闪的那么快
C#定时读取数据库,要么就出错,要么就是一闪一闪的很快  这各是直接运行程序出现的错误
C#定时读取数据库,要么就出错,要么就是一闪一闪的很快  这是逐句调试出现的错误。
public partial class Form1 : Form
{
int i = 0;
int j = 0;
string m = “”;
SqlConnection conn = new SqlConnection(“Data Source=(local);Database=状态表;Trusted_Connection=true;”);//””//server=(local);database=test;uid=sa;pwd=11
string sql = “select * from Table1”;
System.Timers.Timer pTimer = new System.Timers.Timer(2000);//每隔2秒执行一次,没用winfrom自带的,
public Form1()
{
InitializeComponent();
}
private void pTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
dingshi();
}
private void dingshi()        //这个函数就是为了定时读取数据内容
{
if (i == 1)
{
DataGridView dataGridView1 = new DataGridView();
DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader read = cmd.ExecuteReader();
DataSet dataset = new DataSet();
this.dataGridView1.Update();
dt.Load(read);
this.dataGridView1.DataSource = dt;
 this.dataGridView1.DataSource = null;     //这一行代码假如不省略就会一闪一闪的,假如省略就会出现上述错误
}
else
{
DataTable dt_xx = (DataTable)dataGridView1.DataSource;
dt_xx.Rows.Clear();
dataGridView1.DataSource = dt_xx;
}
}
private void button1_Click(object sender, EventArgs e)       //点击开关开始读取数据
{
if (i == 0)
{

i = 1;
conn.Open();
pTimer.Enabled = true;
}
else
{
i = 0;
pTimer.Enabled = false;
conn.Close();
}
dingshi();
}
private void timer1_Tick(object sender, EventArgs e)
{
pTimer.Elapsed += pTimer_Elapsed;//委托,要执行的方法
pTimer.AutoReset = true;//获取该定时器自动执行
Control.CheckForIllegalCrossThreadCalls = false;//这个不太懂,有待研究
m = j.ToString();//以下三行仅仅是为了看下是不是定时刷新了
label1.Text = m;//
j++;//
}
}
}

解决方案

5

数据库操作一定要关闭流对象,read.Close(); 或用using

10

原因是conn是窗体的全局变量,因此在每次执行的时候,这里肯定有上次还没释放正在执行的情况,因此出现错误,解决方法很简单,将conn变为局部变量即可,并且每次用完最好释放对象,如下:
private void dingshi()        //这个函数就是为了定时读取数据内容
{
if (i == 1)
{
SqlConnection conn = new SqlConnection(“Data Source=(local);Database=状态表;Trusted_Connection=true;”);//””//server=(local);database=test;uid=sa;pwd=11
…..
…..
conn.close();conn.dispose();
}
}

5

1.去掉this.dataGridView1.DataSource = null
2.弃用SqlDataReade,直接使用dataset;

5

引用 8 楼 chanjianjiao5475 的回复:
Quote: 引用 6 楼 jhll 的回复:

原因是conn是窗体的全局变量,因此在每次执行的时候,这里肯定有上次还没释放正在执行的情况,因此出现错误,解决方法很简单,将conn变为局部变量即可,并且每次用完最好释放对象,如下:
private void dingshi()        //这个函数就是为了定时读取数据内容
{
if (i == 1)
{
SqlConnection conn = new SqlConnection(“Data Source=(local);Database=状态表;Trusted_Connection=true;”);//””//server=(local);database=test;uid=sa;pwd=11
…..
…..
conn.close();conn.dispose();
}
}

本人这样改了,结果就是会一直闪烁,本人觉得应该是程序在执行this.dataGridView1.DataSource = dt;
this.dataGridView1.DataSource = null;这俩行代码以后会把数据清除,然后窗口就没有数据了,现在问题就是怎么能够让数据保持在datagridview上,然后过2S再清除数据并且重新获取数据库的内容,这个本人就真不知道怎么改了

数据量多大,每条记录有没有唯一标识,有没有差异化加载数据的可能?

5

using(){} 为什么不做try catch 呢?

25

引用 12 楼 chanjianjiao5475 的回复:
Quote: 引用 9 楼 qqamoon 的回复:

数据量多大,每条记录有没有唯一标识,有没有差异化加载数据的可能?

有唯一标识的就是设备号或说是IP地址,这个都是唯一的,只不过就是每隔一段时间新数据会覆盖旧数据。然后就是差异化加载数据,这个本人还不太懂

从理论上给你个建议
定义全局对象,原因是2秒一次打开关闭连接有点吃不消

// 全局对象
DataTable table;
SqlConnection cn;
SqlCommand cmd;
SqlDataAdapter adapter;
string cs = "server=.;database=AdventureWorks;integrated security=sspi;";
// Form_Load
table = new DataTable("humanresources.employee");
//  窗体控件是代码生成的
var bs = new BindingSource { DataSource = table, };
var nav = new BindingNavigator(true) { Dock = DockStyle.Bottom, BindingSource = bs };
var dgv = new DataGridView { DataSource = bs, Dock = DockStyle.Fill };
Controls.AddRange(new Control[] { dgv, nav });
cn = new SqlConnection(cs);
cmd = cn.CreateCommand();
cmd.CommandText = "select * from humanresources.employee";
cmd.CommandType = CommandType.Text;
adapter = new SqlDataAdapter(cmd);
int times = 0;
Timer timer = new Timer();
timer.Interval = 2000;
timer.Tick += (o, g) =>
{
    if (times > 10)
    {
        timer.Stop();
        return;
    }
    table.Rows.Clear();
    adapter.Fill(table);
    // 可能存在的问题:原因是库中的数据没有变化,所以无法判断 adapter fill 的数据能否为最新的
    // 假如数据没有变更,可以取消全局的 adapter 在此处用 using(var adapter = new SqlDataAdapter(cmd))
    times++;
    Console.WriteLine(times);
};
timer.Start();

5

connection用完没有关闭

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C#定时读取数据库,要么就出错,要么就是一闪一闪的很快
喜欢 (0)
[1034331897@qq.com]
分享 (0)