我正在尝试从数据库中选择值并继续从那里更新图表。使用How to update the GUI from another thread in C#?我的代码是:
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)
{
}
}
}
答案 0 :(得分:0)
假设您无法将更改通知推送到客户端,您可能需要某种轮询方法。
您可以设置计时器(请参阅下面的链接)并按经过的时间间隔查询新数据 http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
我不确定你使用的是哪种类型的图表,但是你可以在系列的最后添加新的点(并从系列的前面删除旧的点),这可能会给你类似的东西。您提到的心跳监视器效果...(如果图表不支持您可能需要重建它,或者在每次更新时给它一个全新的系列)
您可能希望调整正在使用的查询,以便每次调用时只获得新的数据点..(其中datetime> [在之前的调用中已检索到的最大日期时间])
实际执行UI更新的代码仍然可以通过调用(..)调用,如您的问题所述......
答案 1 :(得分:0)
好的,这样做:
使用System; 使用System.Collections.Generic; 使用System.ComponentModel; 使用System.Data; 使用System.Drawing; 使用System.Linq; 使用System.Text; 使用System.Windows.Forms; 使用MySql.Data.MySqlClient; 使用System.Threading;
命名空间项目 { 公共部分类Form2:表格 {
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)
{
}
}
}