如何从线程更新表单 [英] how to update a form from a thread

查看:72
本文介绍了如何从线程更新表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Mod总线协议从开发板上检索数据.现在,我想一直以窗口形式更新数据.但是标签仅在单击按钮时更新,我的编码有问题吗?

I am using mod bus protocol to retrieve data from the board. Now I want to update the data in window form all the time. But the label only update when I click button, any problem with my coding?

private void Call(){

private void Call() {

        do
        {
            RequestData(); //get data from mod bus 
            run(a.ToString());


        } while (operation);

    }

    delegate void CallMethod(string Data);

    private void run(string data) {

        if (this.labelO2.InvokeRequired)
        {
            SetRichBoxCallBack d = new SetRichBoxCallBack(run);
            this.Invoke(d, new object[] { data });
        }
        else {
            labelO2.Text = data;
        }

    }
    Thread thread;
    private void button1_Click(object sender, EventArgs e)
    {

        thread = new Thread(new ThreadStart(Call));
        thread.Start();

    }
   public void RequestData()
    {

        if (WriteSerialPort(setMessage, 0, 8))
        {
            Thread.Sleep(1000);
            for (i = 0; i < 19; i++)
            {

                MM[i] = (byte)serialPortBoard.ReadByte();


            }

            a = MM[11] << 8 | MM[12];
            b = (int)MM[13] << 8 | MM[14];


        }

    }

推荐答案

只需将UI更新的调用包装在InvokeRequired ...模式中-而不是从端口获取数据.另外,InvokeRequired...模式也缺少.

Just the call to UI updates should be wrapped within InvokeRequired ... pattern - not the fetch of data from port. Also the InvokeRequired... pattern is missing else.

delegate void UIUpdate(object a, object b);

public void RequestData() {
  ...
  // set type and real value here ;)
  object a = null, b = null;
  var call = new UIUpdate((pa,pb) => {
      labelBin.Text = pa.ToString();
      labelO2.Text = pb.ToString();
  });
  if (this.InvokeRequired) {
    this.Invoke(call, a, b);
  } else {
    call.Invoke(a, b);
  }      
}

private void button1_Click(object sender, EventArgs e) {
  new Thread(() => {
    do {
      RequestData();  // get the data from mod bus protocol
    } while (operation);
  }).Start();    
}

也应该只有一个读取器线程;会做阅读;不要在一个线程中写入/读取.阅读器线程应在表单加载或表单构造函数中启动.

Also there should be only one reader thread; which will do the reading; do not do write/read in one thread. The reader thread should be started on form load or in form constructor.

WriteSerialPort(setMessage, 0, 8)

应在单击按钮时直接调用,而读取应始终在单(独立)线程中.

Should be invoked directly on button click, while read should be always in single (separate) thread.

这篇关于如何从线程更新表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆