完全混淆线程安全调用图表控件

时间:2015-01-24 20:36:00

标签: c# multithreading charts

我正在尝试锻炼如何调用chart1.Series [0] .Points.AddXY(1,4);来自另一个主题。

我一直在尝试调整所有显示使用委托设置文本属性的示例,但我不能让它们使用图表控件。

有人可以帮帮我吗?

delegate void SetTextCallback(string text); //假设text是值而不是Text属性

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

2 个答案:

答案 0 :(得分: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));
                         });
                   }

答案 1 :(得分:0)

使用Progress类,您可能会发现现代方法很有趣。您可以在UI线程中实例化此类对象,并提供lambda函数来更新图表:

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

然后将该对象以某种方式传递给后台工作者,并在您希望更新图表的任何时候调用其Report方法。

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

    }
}

lambda将始终在UI线程中运行,因为Progress对象是在该线程中创建的。

此技术的优点在于,它允许将与UI相关的内容与与背景相关的工作分离。它的发明主要是为了促进reporting progress from asynchronous operations,但它在多线程中也很有用。