【问题标题】:Serial port reading loop in background后台串口读取循环
【发布时间】:2020-06-04 12:32:02
【问题描述】:

有一个 STM32 设备,它通过串行端口在任意 2 秒内发送一个 AES 加密的十六进制数据。所有消息都以换行符结束。我的程序(带有用户界面,而不是控制台)能够从串行读取并解密数据,即使在循环中仍然可以正常工作,但问题是在循环中我不能使用断开功能,所以我的程序留在“无限循环”中。 这是一个代码:

public void button1_Click(object sender, EventArgs e)
{
    try 
    {
        serialPort1.PortName = cBoxComPort.Text;
        serialPort1.BaudRate = 9600;
        serialPort1.DtrEnable = true;
        serialPort1.ReadTimeout = 5000;
        serialPort1.WriteTimeout = 500;
        serialPort1.Open();
        lblStatusCom.Text = "Connected";
        lblMessage.Text = "I am on!";

        while (serialPort1.IsOpen)
        {
            string mgs1 = serialPort1.ReadLine();
            byte[] key = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
            byte[] enc = StringToByteArray(mgs1);
            byte[] dec = Decrypt(enc, key);
            lblMessage.Text = getString(dec);
        }
    }
    catch(Exception err)
    {
        MessageBox.Show(err.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //lblStatusCom.Text = "Disconnected";
    }
}

如何将这个循环过程“置于后台”,以便用户可以点击断开连接,如果他想退出阅读?

【问题讨论】:

  • 设备是否定期发送数据?,你也可以使用DataReceived事件来做这样的事情。这里有一件重要的事情是,如果你把它放在另一个线程上,你不能简单地操作像lblMessage.Text = getString(dec); 这样的 GUI 控件,因为它们在另一个线程上。您需要使用Invoke as in this example
  • @Mong Zhu 该程序在任意 2 秒内发送一个以换行符结尾的长行(大约 200 个字符)。 “打印到串行”的时间是几毫秒。在这种情况下可以使用 DataReceived 还是将其放在后台更好?
  • “程序在任意 2 秒内发送”它是否每 2 秒发送一个字符串?比如在 1:10 然后在 1:12 然后在 1:14 等等?=!
  • @Mong Zhu 是的,每 2 秒更正一次。
  • @Mong Zhu,谢谢 Yuo 现在将先阅读 DataReceived 部分,然后阅读您发送给我的 Invoke 文档。非常感谢您的时间和帮助!

标签: c# while-loop serial-port


【解决方案1】:

这是一个使用 DataReceived 事件的版本:

通过单击按钮,您将打开端口并注册事件

public void button1_Click(object sender, EventArgs e)
{
    try 
    {
        serialPort1.PortName = cBoxComPort.Text;
        serialPort1.BaudRate = 9600;
        serialPort1.DtrEnable = true;
        serialPort1.ReadTimeout = 5000;
        serialPort1.WriteTimeout = 500;
        serialPort1.Open();
        lblStatusCom.Text = "Connected";
        lblMessage.Text = "I am on!";

        serialPort1.DataReceived += portDataReceived;

    }
    catch(Exception err)
    {
        MessageBox.Show(err.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //lblStatusCom.Text = "Disconnected";
    }
}

private void portDataReceived(object sender, EventArgs args)
{
    SerialPort port = sender as SerialPort;

    if (port == null)
    {
        return;
    }

    string mgs1 = port.ReadLine();
    byte[] key = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
    byte[] enc = StringToByteArray(mgs1);
    byte[] dec = Decrypt(enc, key);
    if (lblMessage.InvokeRequired)
    {
        lblMessage.Invoke(new Action(()=> lblMessage.Text = getString(dec)));
    }
    else
    {
        lblMessage.Text = getString(dec);
    }
}

【讨论】:

  • 您好!我现在已经测试了代码,并且工作起来就像一个魅力!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
相关资源
最近更新 更多