2

我有一个关于向图表添加点的问题。

我的 Windows 窗体应用程序正在使用线程从另一台服务器获取 Y 值。每 500 毫秒我会得到一个新值(字符串),应该将其添加为一个点,但我不知道该怎么做。如果这些点将实时显示,而不仅仅是在结束过程之后显示,那就太好了。我认为这不是一个真正困难的问题,但我没有找到解决方案。

线:

 private void Work()
    {
        int counter = 0;

        while (true)
        {
            counter++;
            WebClient code = new WebClient();
            speed_str = code.DownloadString("http://192.168.19.41/speedfile.html");
            speedval = Convert.ToDouble(speed_str);
            Console.WriteLine(speedval.ToString() + "\n Times executed: "  + counter);
            Thread.Sleep(1000);
        }
    }

配置和图表

 Thread thread = new Thread(new ThreadStart(this.Work));
        thread.IsBackground = true;
        thread.Name = "My Worker.";
        thread.Start();

        //Speed
        Series speed = new Series("Speed[m/s]");

        speed.ChartType = SeriesChartType.Spline;


        //Engines Left 
        engleft = new Series("Engines Left");

        engleft.ChartType = SeriesChartType.Spline;

        Engines.Series.Add(engleft);

        engleft.Points.Clear();

        string speed_read = Console.ReadLine();

感谢帮助 :)

4

1 回答 1

0

Producer-Consumer您手头上有一个经典场景。

这意味着一个线程产生一个项目(后台线程)
,而另一个线程消耗它(UI线程)。

生产者和消费者之间进行通信的一种方法是使用事件:

    class Producer
    {

    public event EventHandler<double> YSeriesEvent;
    private Thread thread;

    public Producer()
    {
        thread = new Thread(new ThreadStart(this.Work));
        thread.IsBackground = true;
        thread.Name = "My Worker.";     
    }

    public void Start()
    {
        thread.Start();
    }

    private void Work()
    {
        int counter = 0;

        while (true)
        {
            counter++;
            WebClient code = new WebClient();
            speed_str = code.DownloadString("http://192.168.19.41/speedfile.html");
            speedval = Convert.ToDouble(speed_str);
            YSeriesEvent?.Invoke(this, speedval);
        }
    }
   }

然后,在您的表格中,您可以这样做:

class MyForm : Form
{

private Producer producer;

public MyForm()
{
    producer = new Producer();
    producer.YSeriesEvent += MyHandler ;
    Load+= (sender, args) => producer.Start();
}

private void MyHandler(object o, double val)
{
    Invoke(new Action(() =>
    {
           //add value to chart here
    }));
}
}   

请注意,WinForms 是单线程的,这意味着没有线程可以直接在 UI 元素上工作,除非它是 UI 线程。
这就是我调用该Invoke方法的原因——它只是卸载要在 UI 线程上执行的工作。

于 2017-01-28T13:31:33.200 回答