0

I'm trying to workout how to call chart1.Series[0].Points.AddXY(1, 4); from another thread.

I have been trying to adapt the examples which all show setting a text property using a delegate but I can't get them to work with the chart control.

could someone please help me?

delegate void SetTextCallback(string text);//assume text is the value and not the Text property

 private void chartRefresh()
    {
        while (true)
        {
            //code to refresh chart
            for (int i = 0; i < 30; i++)
            {
                if (this.chart1.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    this.chart1.Series[0].Points.AddXY(i, i + 2); 
                }

                chart1.Series[0].Points.AddXY(i, i + 2);
                Thread.Sleep(500);
            }

        }

private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the 
            // calling thread to the thread ID of the creating thread. 
            // If these threads are different, it returns true. 
            if (this.chart1.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.chart1.Series[0].Points.AddXY(1, 4);
            }
        }
RTFS
  • 115
  • 1
  • 10

2 Answers2

0
while (true)
              {

                  for (int i = 0; i < 20000; i++)
                  {
                        Temp ++;
                        chart1 .Invoke((MethodInvoker)delegate
                        {
                            // Running on the UI thread
                            Series.Points.AddXY(i, random.Next(0,100));
                         });
                   }
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    Welcome to Stack Overflow. Code dumps without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please [edit] your question and explain how it works better than what the OP provided. – ChrisGPT was on strike May 16 '20 at 22:37
0

You may find interesting the modern approach, using the Progress class. You can instantiate such an object in the UI thread, supplying the lambda function that will update the chart:

private IProgress<int> _chartProgress

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _chartProgress = new Progress<int>(i =>
    {
        this.chart1.Series[0].Points.AddXY(i, i + 2);
    });
}

Then pass this object somehow to the background worker, and invoke its Report method any time you want the chart to be updated.

private void ChartRefresh(IProgress<int> progress)
{
    while (true)
    {
        //code to refresh chart
        for (int i = 0; i < 30; i++)
        {
            progress.Report(i);
            Thread.Sleep(500);
        }

    }
}

The lambda will always run in the UI thread, because the Progress object was created in that thread.

The advantage of this technique is that it allows decoupling the UI-related stuff from the background-related work. It was invented primarily for facilitating reporting progress from asynchronous operations, but it can be useful in multithreading too.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104