데이터베이스에서 값을 선택하고 거기에서 그래프를 계속 업데이트하려고합니다.. 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)
{
}
}
}
Invoke ...하지만 독자적으로 코드가 실행됩니다.타이머가 사용될 수있는주기적인 업데이트를 트리거하기위한 무언가가 필요합니다 (다른주기적인 이벤트를 첨부하지 않는 한) ... 타이머 이벤트가 Invoke 코드를 호출 할 수 있습니다 ... BackgroundWorker는 데이터 검색을 다른 스레드로 푸시하려는 경우 (작업자가 완료되면 UI 새로 고침을 트리거 할 수 있음) – Why
당신은 사용할 수 있습니다 중 하나를 사용할 필요가 ... 타이머를 사용하려는 해달라고 –
업데이트 된 질문보기. 나는 백그라운드 작업자에서 반복 및 수면을 볼 수 있습니다. 올바른 스레드에서 UI 업데이트 코드를 가져올 필요가 ... DoWork 메서드 내에서 this.chartTemperature 변경 주위에 Invoke 호출을 시도 할 수 있습니다 ... 그러나 이것은 BackgroundWorker (일반적으로 루프의 비정상적인 사용이라고 생각합니다 수면은 타이머처럼 행동하게 만든다.) –