0

Here I have a chart (graph1) that normally should add a random point every 1second. but it doesn't... I tried to find out what the problem is but here I don't have anymore ideas... The timer is started, label1 change every seconds but the chart doesn't change... with button one when I click it adds a new point. what did I miss? please help... thanks a lot.

namespace Test_Chart1
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
        graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
        graph1.ChartAreas[0].AxisX.ScaleView.Size = 40;
        System.Timers.Timer _Timer1s = new System.Timers.Timer(1000);   //object
        _Timer1s.Elapsed += _Timer1sElapsed;                            //event in object
        _Timer1s.Start();                                               //start counting            
    }
    private void _Timer1sElapsed(object sender, EventArgs e)//Timer each 100ms
    {        
        if (label1.BackColor == Color.Red)
        {
            label1.BackColor = Color.Blue;
            PutValueInGraph1();              
        }
        else label1.BackColor = Color.Red;             
    }

    private void button1_Click(object sender, EventArgs e)
    {
        PutValueInGraph1();
    }
    private void PutValueInGraph1()
    {
        graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
        graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
        graph1.ChartAreas[0].AxisX.ScaleView.Size = 100;
        Random Rand_Value = new Random();
        int ValueToAdd = Rand_Value.Next(1, 100);
        listBox1.Items.Add(ValueToAdd.ToString());
        graph1.Series["Data1"].Points.AddY(ValueToAdd);
        if (graph1.ChartAreas[0].AxisX.Maximum-10 > graph1.ChartAreas[0].AxisX.ScaleView.Size)
        {
               graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum);
            graph1.Series["Data1"].Points.RemoveAt(0);
        }
    }
}
}

ok here is the new one:

public partial class Form1 : Form
{
static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

    public Form1()
    {
        InitializeComponent();
        myTimer.Tick += new EventHandler(TimerEventProcessor);
        myTimer.Interval = 1;           
    }

    private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
    {
        Random Rand_Value = new Random();
        int ValueToAdd = Rand_Value.Next(1, 100);
        listBox1.Items.Add(ValueToAdd.ToString());
        graph1.Series["Data1"].Points.AddY(ValueToAdd);
        if (graph1.ChartAreas[0].AxisX.Maximum - 10 > graph1.ChartAreas[0].AxisX.ScaleView.Size)
        {
            graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum);
            graph1.Series["Data1"].Points.RemoveAt(0);
        }
    }
    private void btn_Start_Click_1(object sender, EventArgs e)
    {
        graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
        graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true;
        graph1.ChartAreas[0].AxisX.ScaleView.Size = 100;
        myTimer.Start();
        BlinkLed.BackColor = Color.YellowGreen;
    } 
  private void btn_Stop_Click(object sender, EventArgs e)
    {
        myTimer.Stop();
        BlinkLed.BackColor = Color.AliceBlue;
    }   
}  

Do you think it's better? What about the changing thread?

If I had a button:

   private void PutValueInGraph1()
    {
        Random Rand_Value = new Random();
        int ValueToAdd = Rand_Value.Next(1, 100);
        listBox1.Items.Add(ValueToAdd.ToString());
        graph1.Series["Data1"].Points.AddY(ValueToAdd);
        if (graph1.ChartAreas[0].AxisX.Maximum-10 > graph1.ChartAreas[0].AxisX.ScaleView.Size)
        {
            graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum);
            graph1.Series["Data1"].Points.RemoveAt(0);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {//try to raise exception
        PutValueInGraph1();
    }

and I change the event like this:

   private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
    {//try to raise exception
        PutValueInGraph1();
    }

The data input accelerate when I'm started the timer and I click all the time on the button1.

Why is there no exception as tom_imk said?? because we can access the same function at the same time....?

Thanks for your answers.

JudgeDreed
  • 143
  • 1
  • 13

2 Answers2

0

I'm surprised you didn't get an exception. You are manipulating UI elements outside the UI thread, something you musn't do, ever.

Refer to the answer in this question: How to update the GUI from another thread in C#?

EDIT: To make clear why the timerelapsed method does not run on the UI thread: It's simply the wrong class that is used here. So the easy solution would be to not created a System.Timers.Timer in the Form-constructor but to drop a timer on the form in the form designer and use that instead. The solution by sowjanya attaluri should be marked as the correct answer.

Community
  • 1
  • 1
tom_imk
  • 165
  • 2
  • 11
  • I don't see the point. Are you talking about label1? If so Label1 is only modified in the event timerelapsed... what other thread is accessing it ?? – JudgeDreed Jun 30 '16 at 06:50
  • The first version of the code of the OP uses a System.Timers.Timer while he should have been using a System.Windows.Forms.Timer incorporated in the form designer.. i.e. the timerelapsed runs outside the UI thread. I recreated the exact code (first version posted) and got consistent exceptions. I will edit my answer to point to the time specifically. – tom_imk Jun 30 '16 at 07:40
0

I tried below sample code and it is working fine for me.

    public Form7()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        chart1.ChartAreas[0].AxisX.Maximum = 100;
        chart1.ChartAreas[0].AxisX.Minimum = 0;
        chart1.ChartAreas[0].AxisX.Interval = 1;

        timer1.Start();           
    }

    private void timer1_Tick(object sender, EventArgs e)
    {  
        Random Rand_Value = new Random();
        int ValueToAdd = Rand_Value.Next(1, 100);
        chart1.Series[0].Points.AddY(ValueToAdd);
    }
sowjanya attaluri
  • 903
  • 2
  • 9
  • 27