Search code examples
multithreadingchartstimer

updating chart real time Cross-thread operation not valid


I'm trying to build a GUI for my application. I'm stuck on one problem. I try to use timer "OnTImedEvent" to call my function to update the chart. Unfortunately, MVS gives me a "Cross-thread operation not valid". I've came across some tips, regarding something called delegate but I can't manage to get it working. Since I'm nooby in windowsFormsApp (started today) I'm asking for your help. Here's my code:

using System;
using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        bool state = false;
        private static System.Timers.Timer timer;
        public Form1()
        {
            InitializeComponent();
            timer = new System.Timers.Timer(10);
            timer.Elapsed += OnTimedEvent;
            timer.AutoReset = true;
            timer.Enabled = true;      
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine("a\n");
            }
            else
                MessageBox.Show("Brak połączenia z urządzeniem");
        }

        private void button4_Click(object sender, EventArgs e)
        {

            if (serialPort1.IsOpen)
            {
                Form2 form2 = new Form2(serialPort1);
                form2.Show();
            }
            else
                MessageBox.Show("Brak połączenia z urządzeniem");
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            comBoxPort.Items.AddRange(ports);
        }

        private void btnCon_Click(object sender, EventArgs e)
        {
            if (state)
            {
                state = false;
                btnCon.ForeColor = Color.Red;
                try
                {
                    serialPort1.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw;
                }
            }
            else
            {
                state = true;
                btnCon.ForeColor = Color.Green;
                try
                {
                    serialPort1.PortName = comBoxPort.Text;
                    serialPort1.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw;
                }
            }

        }

        private void btnRoll_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine("s\n");
            }
            else
                MessageBox.Show("Brak połączenia z urządzeniem");
        }

        private void btnYAW_Click(object sender, EventArgs e)
        {
            drawChart();
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine("d\n");
            }
            //else
                //MessageBox.Show("Brak połączenia z urządzeniem");
        }
        private void drawChart()
        {
            chart1.Series["PITCH"].Points.AddY(21);
            chart1.Series["ROLL"].Points.AddY(122);
            chart1.Series["YAW"].Points.AddY(13);
        }
        public delegate void drawChartCallback();
        private void chart1_Click(object sender, EventArgs e)
        {

        }        
        private void OnTimedEvent(Object source, ElapsedEventArgs e)
        {
            drawChart();
        }
    }
}

Thanks in advance for your help.


Solution

  • While its not the best way to do it, for a beginner the easist way to avoid the problem is to use the following variable form.CheckForIllegalCrossThreadCalls = false;