0

データベースから値を選択して、そこからグラフを更新しようとしています。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)
        {

        }

    }
}
4

2 に答える 2

0

変更の通知をクライアントにプッシュする方法がないと仮定すると、何らかのポーリング アプローチが必要になる可能性があります。

タイマーを設定し (以下のリンクを参照)、経過した間隔で新しいデータを照会できます。
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx

使用しているグラフの種類はわかりませんが、シリーズの最後に新しいポイントを追加する (そしてシリーズの先頭から古いポイントを削除する) ことができる場合があります。あなたが言及した監視効果...(チャートがそれをサポートしていない場合は、再構築する必要があるか、更新ごとにまったく新しいシリーズを提供する必要があります)

各呼び出しで新しいデータ ポイントのみを取得するように、使用しているクエリを調整することをお勧めします。

UI の更新を実際に実行するコードは、質問で説明されているように、invoke(..) を介して呼び出すことができます...

于 2013-07-17T13:22:54.083 に答える