C # постоянно обновлять графический интерфейс от фонового работника - PullRequest
3 голосов
/ 31 марта 2010

Я создал графический интерфейс (winforms) и добавил фонового работника для запуска в отдельном потоке. Фоновый работник должен постоянно обновлять 2 метки. Фоновый поток должен начинаться с нажатия кнопки 1 и выполняться вечно.

    class EcuData 
    {
        public int RPM { get; set; }
        public int MAP { get; set; }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        EcuData data = new EcuData
        {
            RPM = 0,
            MAP = 0
        };
        BackWorker1.RunWorkerAsync(data);
    }

    private void BackWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        EcuData argumentData = e.Argument as EcuData;
        int x = 0;
        while (x<=10)
        {
            //
            // Code for reading in data from hardware.
            //
            argumentData.RPM = x;           //x is for testing only!
            argumentData.MAP = x * 2;       //x is for testing only!
            e.Result = argumentData;
            Thread.Sleep(100);
            x++;
       }
    private void BackWorker1_RunWorkerCompleted_1(object sender,  RunWorkerCompletedEventArgs e)
    {
        EcuData data = e.Result as EcuData;
        label1.Text = data.RPM.ToString();
        label2.Text = data.MAP.ToString();
    }
}

Приведенный выше код только что обновил графический интерфейс, когда backgroundworker завершил свою работу, и это не то, что я ищу.

Ответы [ 3 ]

9 голосов
/ 31 марта 2010

Вам нужно взглянуть на BackgroundWorker.ReportProgess .

Вы можете использовать его для периодической передачи объекта методу в главном потоке, который может обновлять метки для вас.

3 голосов
/ 31 марта 2010

Вы можете использовать System.Threading.Timer и обновить пользовательский интерфейс из метода обратного вызова таймера, вызвав BeginInvoke в главной форме.

uiUpdateTimer = new System.Threading.Timer(new TimerCallback(
            UpdateUI), null, 200, 200);

private void UpdateUI(object state)
{
    this.BeginInvoke(new MethodInvoker(UpdateUI));
}

private void UpdateUI()
{
    // modify labels here
}
1 голос
/ 31 марта 2010
class EcuData
    {
        public int RPM { get; set; }
        public int MAP { get; set; }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        EcuData data = new EcuData
        {
            RPM = 0,
            MAP = 0
        };
        BackWorker1.RunWorkerAsync(data);
    }

    private void BackWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        EcuData argumentData = e.Argument as EcuData;
        int x = 0;
        while (x<=10)
        {
            e.Result = argumentData;
            Thread.Sleep(100);
            this.Invoke((MethodInvoker)delegate
            {
                label1.Text = Convert.ToString(argumentData.RPM = x);           //send hardware data later instead, x is for testing only!
                label2.Text = Convert.ToString(argumentData.MAP = x * 2);       //send hardware data later instead, x is for testing only!
            });
            x++;
       }
    }

Это работает, но это правильный способ сделать это?

...