从数据库中拾取值时更新Graph
本文关键字:更新 Graph 数据库 | 更新日期: 2023-09-27 18:23:39
我正试图从数据库中选取值,并从那里不断更新图形。使用C#中的如何从另一个线程更新GUI?我的代码是:
private void button1_Click(object sender, EventArgs e)
{
string myConnection = "datasource=localhost;port=3306;username=root;password=root";
MySqlConnection conDataBase = new MySqlConnection(myConnection);
MySqlCommand cmdDataBase = new MySqlCommand(" select * from data.test; ", conDataBase);
MySqlDataReader myReader;
this.Invoke((MethodInvoker)delegate
{
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
this.chart1.Series["Series1"].Points.AddXY(myReader.GetString("datetime"), myReader.GetInt32("temp"));
}
conDataBase.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
});
}
虽然我没有得到任何错误,但我认为它不起作用,因为图是恒定的/静态的。任何建议我主要想要的是这个图根据数据库中的新值不断更新。。。像心跳监测器之类的东西
有什么建议。。。问候
编辑:我也尝试过使用后台工作者,但在那里我也得到了以下按钮点击:
Cross thread operation not valid: Control 'charTemperature' accessed from athread other than the thread it was created on
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using System.Threading;
namespace project
{
public partial class Form2 : Form
{
private BackgroundWorker bw = new BackgroundWorker();
public Form2()
{
InitializeComponent();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = false;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnTemperature_Click(object sender, EventArgs e)
{
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
//this.Invoke((MethodInvoker)delegate
// {
/* string myConnection = "datasource=localhost;port=3306;username=root;password=root";
MySqlConnection conDataBase = new MySqlConnection(myConnection);
MySqlCommand cmdDataBase = new MySqlCommand(" select * from data.test; ", conDataBase);
MySqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
this.chartTemperature.Series["Temperature"].Points.AddXY(myReader.GetString("datetime"), myReader.GetInt32("temp"));
}
conDataBase.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//});*/
}
private void btnStopUpdating_Click(object sender, EventArgs e)
{
if (bw.WorkerSupportsCancellation == true)
{
bw.CancelAsync();
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
string myConnection = "datasource=localhost;port=3306;username=root;password=root";
MySqlConnection conDataBase = new MySqlConnection(myConnection);
MySqlCommand cmdDataBase = new MySqlCommand(" select * from data.test; ", conDataBase);
MySqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
this.chartTemperature.Series["Temperature"].Points.AddXY(myReader.GetString("datetime"), myReader.GetInt32("temp"));
System.Threading.Thread.Sleep(1000);
}
conDataBase.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
}
又一次徒劳的尝试。。。点击按钮时不会发生任何事情。。。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using System.Threading;
namespace project
{
public partial class Form2 : Form
{
private BackgroundWorker bw = new BackgroundWorker();
public string vdatetime;
public Int32 vtemp;
public Form2()
{
InitializeComponent();
bw.WorkerSupportsCancellation = true;
// bw.WorkerReportsProgress = false;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnTemperature_Click(object sender, EventArgs e)
{
//if (bw.IsBusy != true)
//{
this.bw.RunWorkerAsync();
//}
//this.Invoke((MethodInvoker)delegate
// {
/* string myConnection = "datasource=localhost;port=3306;username=root;password=root";
MySqlConnection conDataBase = new MySqlConnection(myConnection);
MySqlCommand cmdDataBase = new MySqlCommand(" select * from data.test; ", conDataBase);
MySqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
this.chartTemperature.Series["Temperature"].Points.AddXY(myReader.GetString("datetime"), myReader.GetInt32("temp"));
}
conDataBase.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//});*/
}
private void btnStopUpdating_Click(object sender, EventArgs e)
{
// if (bw.WorkerSupportsCancellation == true)
//{
this.bw.CancelAsync();
//}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if ((worker.CancellationPending == true))
{
e.Cancel = true;
//break;
}
else
{
string myConnection = "datasource=localhost;port=3306;username=root;password=root";
MySqlConnection conDataBase = new MySqlConnection(myConnection);
MySqlCommand cmdDataBase = new MySqlCommand(" select * from data.test; ", conDataBase);
MySqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
//this.Invoke((MethodInvoker)delegate
//{
while (myReader.Read())
{
vdatetime = myReader.GetString("datetime");
vtemp = myReader.GetInt32("temp");
//Thread.Sleep(300);
// this.chartTemperature.Series["Temperature"].Points.AddXY(myReader.GetString("datetime"), myReader.GetInt32("temp"));
// System.Threading.Thread.Sleep(1000);
}
conDataBase.Close();
// });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
// The user canceled the operation.
MessageBox.Show("Operation was canceled");
}
else if (e.Error != null)
{
// There was an error during the operation.
string msg = String.Format("An error occurred: {0}", e.Error.Message);
MessageBox.Show(msg);
}
else
{
this.chartTemperature.Series["Temperature"].Points.AddXY(vdatetime, vtemp);
}
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
}
假设您无法将更改通知推送到客户端,那么您可能需要某种轮询方法。
您可以设置一个计时器(请参阅下面的链接),并在经过的时间间隔内查询新数据
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
我不确定你使用的是什么样的图表,但你可以在系列的末尾添加新的点(并从系列的前面删除旧的点),这可能会给你带来你提到的心跳监视器效果。。。(如果图表不支持,你可能需要重新构建它,或者在每次更新时给它一个全新的系列)
您可能希望调整正在使用的查询,以便在每次调用中只获得新的数据点。。(其中日期时间>[上次通话中已检索到的最大日期时间])
实际执行UI更新的代码仍然可以通过invoke(..)调用,如您的问题中所述。。。
好的,这样就可以了:
使用系统;使用System.Collections.Generic;使用System.ComponentModel;使用System.Data;使用System.Drawing;使用System.Linq;使用System.Text;使用System.Windows.Forms;使用MySql.Data.MySqlClient;使用System.Threading;
命名空间项目{公共分部类Form2:Form{
public delegate void AddGraphPointsTemp();
public AddGraphPointsTemp myDelegate1;
Thread tempThread;
string myConnection;
MySqlConnection conDataBase;
MySqlCommand cmdDataBase;
MySqlDataReader myReader;
public Form2()
{
InitializeComponent();
myDelegate1 = new AddGraphPointsTemp(AddGraphPointsMethodTemp);
myConnection = "datasource=localhost;port=3306;username=root;password=root";
conDataBase = new MySqlConnection(myConnection);
cmdDataBase = new MySqlCommand(" select * from data.test; ", conDataBase);
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
}
private void btnExit_Click(object sender, EventArgs e)
{
conDataBase.Close();
Application.Exit();
}
public void AddGraphPointsMethodTemp()
{
try
{
myReader.Read();
chartTemperature.Series["Temperature"].Points.AddXY(myReader.GetString("datetime"), myReader.GetInt32("temp"));
chartTemperature.Update();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnTemperature_Click(object sender, EventArgs e)
{
tempThread = new Thread(ThreadFunction1);
tempThread.Start(this);
}
public static void ThreadFunction1(Object obj)
{
while (true)
{
Form2 myForm2 = (Form2)obj;
myForm2.Invoke(myForm2.myDelegate1);
Thread.Sleep(300);
}
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
}