C#如何在下一个命令之前按顺序读取串口通信中的响应?

问题描述 投票:0回答:1

我正在用 C# 编写一个程序,用于处理串行端口通信、写入命令和读取响应。我向 COM 端口发送了大约 50 个命令。在我的屏幕上,我需要按顺序显示发送的命令和接收的响应。例如,命令 1 - 响应 1、命令 2 - 响应 2,依此类推。但我的程序首先显示 50 个命令,然后显示 50 个相应的响应。这是我的 DataReceivedHandler 函数:

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
      Thread.Sleep(2000);
      SerialPort sp = (SerialPort)sender;
      data = sp.ReadLine();
      setTextInReplyBox(data);
}

setTextInReplyBox 函数将值显示到文本框中。我尝试使用 async wait 但它不起作用。

c# webforms serial-port
1个回答
0
投票

1.事件中定义串口不可以。 2.使用Thread.Sleep()使程序出错。 3.创建一个队列来保存发送过程中的消息。 4.使用异步编程以获得更好的结果。

所以我们基于以下方法进行: A. 创建一个队列来保存您的命令。在开始通信之前将所有 50 个命令排入队列。 B. 收到响应后,将下一个命令从队列中出列并发送。 C. 使用异步方法,而不是使用 Thread.Sleep(2000)(它会阻塞线程)。 D. 订阅DataReceived事件并异步处理。

所以程序将如下所示:

    private static SerialPort _serialPort;
    private static Queue<string> _commandQueue = new Queue<string>();

    static async Task Main(string[] args)
    {
        // Initialize your SerialPort settings
        _serialPort = new SerialPort("COM1", 9600);
        _serialPort.DataReceived += DataReceivedHandler;
        _serialPort.Open();

        // Enqueue your 50 commands
        EnqueueCommands();

        // Start sending commands
        await SendCommandsAsync();

        // Clean up
        _serialPort.Close();
    }

    private static void EnqueueCommands()
    {
        // Enqueue your 50 commands here
        _commandQueue.Enqueue("Command1");
        // ...
        _commandQueue.Enqueue("Command50");
    }

    private static async Task SendCommandsAsync()
    {
        while (_commandQueue.Count > 0)
        {
            string command = _commandQueue.Dequeue();
            _serialPort.WriteLine(command);

            // Wait for response asynchronously
            await WaitForResponseAsync();
        }
    }
    private static async Task WaitForResponseAsync()
    {
        // Implement your response handling logic here
        // For example, read the response using _serialPort.ReadLine()

        // Simulate waiting for response (replace with actual logic)
        await Task.Delay(2000);

        // Display the response (use your setTextInReplyBox function)
        string response = "Response for " + command; // Replace with actual response
        Console.WriteLine(response);
    }

    private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        // Handle data received (if needed)
    }
© www.soinside.com 2019 - 2024. All rights reserved.