从数据库中拾取值时更新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)
        {
        }
    }
}

从数据库中拾取值时更新Graph

假设您无法将更改通知推送到客户端,那么您可能需要某种轮询方法。

您可以设置一个计时器(请参阅下面的链接),并在经过的时间间隔内查询新数据
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)
    {
    }
}

}