C# - 后台工作人员通过串行从 Arduino 连续获取数据

标签 c# serial-port arduino backgroundworker

所以我有这个 C# 应用程序,它从 Arduino 获取值(6 个变量)。最初我使用了一个计时器,每 100 毫秒调用一些读取函数,但它挂起我的 UI 并且响应有点重。我想使用一个后台 worker 来连续读取这些变量。我将这些读取调用放在 DoWork 方法中,并将值放入 C# 的变量中,并将它们分配到标签或其他内容中。但这不起作用。 (抱歉我的英语)

namespace testtemp
{
    public partial class tempreaderform : Form
    {
        public tempreaderform()
        {
            InitializeComponent();
        }

communicator comport = new communicator();
Boolean portConnection = false;
String red_light1;

private void button1_Click(object sender, EventArgs e)
        { 
            if (comport.connect(57600, "I'M ARDUINO", 4, 8, 16))
            {
                label1.Text = "Connection Successful - Connected to  "+comport.port;
                portConnection = true;
                backgroundWorker1.RunWorkerAsync(); // I am not sure if here I should start the backgroundworker.
            }
            else
            {
                label1.Text = "Not connected . . . ";
                portConnection = false;
            }
        }

        private void groupBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics ellipse1 = groupBox1.CreateGraphics();

            Brush red_on = new SolidBrush(Color.Red);
            Brush red_off = new SolidBrush(Color.DarkRed);

            label2.Text = "Red : " + red_light1; //Here is a label which I want to show "1" if "red_light1" is "1" and "0" if "red_light1" is "0"

            if (red_light1 == "1") ellipse1.FillEllipse(red_on, 250, 133, 24, 24);
                            else ellipse1.FillEllipse(red_off, 250, 133, 24, 24); // Here is what I really want to do (the label.Text part was only to see the value) I want to color a ellipse depending on "red_light1" value.

        }



private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                red_light1 = comport.message(4, 8, 32);
            }
        }
}
}
}

注意:我在 DoWork 方法中尝试了这个“label1.Text = red_light1”,但它说我无法为另一个线程中创建的变量赋值,就像这样。

最佳答案

“问题”是后台工作人员生活在另一个线程中,而您试图在 UI 线程中使用。并且消息不会在那里传达。

共有三个选项:

  1. 要使用 RunWorkerCompleted 事件:您必须使用计时器每 X 毫秒运行一次后台工作程序。

    private void timer1_Tick(object sender, EventArgs e) {
      this.backgroundworker.RunWorkerAsync();
    }
    
    
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
      e.Result = comport.message(4, 8, 32);
    }
    
    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
      label2.Text = e.Result.ToString();
    }
    
  2. 使用BeginInvoke设置文本

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            this.BeginInvoke((Action)(() => { label2.Text = comport.message(4, 8, 32); });
    
           // add some delay here as well...
        }
    }
    
  3. 使用Task代替backgroundworker并在计时器中调用它。

    private void timer1_Tick(object sender, EventArgs e) {
      Task.Run(() => {
        this.BeginInvoke((Action)(() => { label2.Text = comport.message(4, 8, 32); });
       });
    }
    

关于C# - 后台工作人员通过串行从 Arduino 连续获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29819552/

相关文章:

c# - 单元测试看不到我的方法

c# - Visual Studio 在停止调试器后保持句柄打开

c# - 我已经编写了一个线程池,如何通知使用它的方法任务已经完成?

c# - 将 String.Empty 发送到存储过程

c# - 结合RFID读写器在arduino中接收USB串口数据

c++ - 更改 Qt 访问的 Comport

c++ - cpp程序在访问类成员的成员变量时挂起

python - 串行通信 Python 到 Arduino - 无法识别回车

windows - 如何让 Matlab 确定操作系统是 windows 还是 mac?所以要找到所有串行 USB 连接

serial-port - 我怎样才能 "reset"Arduino 板?