本人正在做一个从数据库实时读取数据显示到datagridview中,但是就是一直出现问题,本人是用定时器来定时读取数据库并且显示数据的,,本人想问一下下应该怎么改代码,可以解决这个问题,主要是希望不要闪的那么快
这各是直接运行程序出现的错误
这是逐句调试出现的错误。
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)
{
这各是直接运行程序出现的错误
这是逐句调试出现的错误。
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();
}
}
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;
2.弃用SqlDataReade,直接使用dataset;
5
数据量多大,每条记录有没有唯一标识,有没有差异化加载数据的可能?
5
using(){} 为什么不做try catch 呢?
25
数据量多大,每条记录有没有唯一标识,有没有差异化加载数据的可能?
有唯一标识的就是设备号或说是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用完没有关闭