C# Добавяне на точки към графиката в реално време

Имам въпрос относно добавянето на точки към диаграмите.

Моето приложение за Windows forms използва нишка, за да получи стойността Y от друг сървър. На всеки 500 ms получавам нова стойност (низ), която трябва да се добави като точка, но нямам представа как да направя това. Би било много хубаво точките да се показват в реално време, а не само след приключване на процеса. Мисля, че това не е наистина труден въпрос, но не намерих решение.

Тема:

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

Благодаря за помощта :)


person Tim B.    schedule 28.01.2017    source източник
comment
Коя UI Framework използвате? (Моля, редактирайте публикацията си, така че да отразява това)   -  person Eyal Perry    schedule 28.01.2017
comment
Също така ще помогне, ако публикувате своя код, така че потребителите да видят къде сте заседнали :)   -  person Eyal Perry    schedule 28.01.2017
comment
@EyalPerry Предполагам, че той използва Winforms и собствения контролен елемент chartview... (в етикетите)   -  person 97hilfel    schedule 28.01.2017
comment
Предполагам, че сте опитали да добавите елементи в контролата от фоновата нишка, получили сте изключение и след това просто сте изчакали нишката да приключи, преди да добавите цялата група. Ако случаят е такъв, имам отговор за вас. Ако не - моля уточнете.   -  person Eyal Perry    schedule 28.01.2017
comment
@97hilfel О, съжалявам - не правя WinForms, така че нямах представа :) PS, таговете бяха добавени след моя коментар.   -  person Eyal Perry    schedule 28.01.2017
comment
@EyalPerry съжалявам, че не видях това..   -  person 97hilfel    schedule 28.01.2017
comment
Надявам се, че добавеният код ще помогне малко. Знам, чеs not the best but hopefully it е възможно да се работи с него :)   -  person Tim B.    schedule 28.01.2017
comment
Всичко е наред. Погледнете отговора ми.   -  person Eyal Perry    schedule 28.01.2017


Отговори (1)


Имате класически 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 резба.

person Eyal Perry    schedule 28.01.2017