0

I am trying to pick values from the database and keep updating the graph from there. Using How to update the GUI from another thread in C#? my code is:

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);
                    }
                });
        }

Though i do not get any error, i dont think its working as the graph is constant/static. Any suggestions. What i basically want is that this graph keeps updating based on the new values in the database...something like a heart beat monitor or to that effect.

Any suggestions...Regards

Edit: I also tried using background worker but there also i get the following on button click:

Cross thread operation not valid: Control 'charTemperature' accessed from athread other than the thread it was created on

The code:

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)
        {

        }


    }
}

One more futile attempt...nothing happens on button click...

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)
        {

        }

    }
}
Community
  • 1
  • 1
Why
  • 626
  • 11
  • 29

2 Answers2

0

Assuming you have no way of pushing notification of changes to the client, you are likely going to need some kind of polling approach.

You could setup a timer (see link below) and query for new data at elapsed intervals.
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx

I'm not sure what kind of chart you are using, but you may be able to add new points to the end of the series (and remove old ones from the front of the series) which may give you something like the heart-beat monitor effect that you mentioned... (if the chart doesn't support that you may need to rebuild it, or give it an entirely new series on each update)

You probably want to adjust the query you are using so that you get only new data points on each call.. ( where datetime > [maximum datetime already retrieved in a previous call] )

The code that actually performs the UI update could still be called through an invoke(..) as described in your question...

Phill_P
  • 399
  • 2
  • 6
  • i dont want to use Timers...I need to use either Invoke or the BackgroundWorker – Why Jul 17 '13 at 14:12
  • 1
    You can use Invoke...but on its own, that will just cause the code to run once... You also need something to trigger the periodic updates which is where a timer could be used (unless you have some other periodic event to attach to)... the timer event could call the Invoke code... A BackgroundWorker could be used if you want to push the data retrieval to another thread (and you could trigger the UI refresh once the worker completes).. – Phill_P Jul 17 '13 at 14:27
  • 1
    Looking at the updated question.. I can see you have a loop and a sleep in the background worker... you would need to get the UI update code back on the correct thread... you could try the Invoke call just around the this.chartTemperature change within the DoWork method... however I think this is unusual use of a BackgroundWorker (basically the loop and sleep is making it act like a timer) – Phill_P Jul 17 '13 at 14:39
0

Ok this does it:

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 {

    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)
    {

    }

}

}

Why
  • 626
  • 11
  • 29