【问题标题】:Correct Implementation of Async SerialPort ReadAsync SerialPort Read 的正确实现
【发布时间】:2020-08-03 04:07:59
【问题描述】:

我在这里阅读了一些建议将port.BaseStream.ReadAsync() 与waith async / await 一起使用。我不清楚实现这一点的最佳方法是什么?

我是否仍然使用 event_handler 并使其异步/可等待?

private async void myPort_DataReceived(object sender,      SerialDataReceivedEventArgs e)
        {
            byte[] buffer = new byte[myPort.BytesToRead];
            await (myPort.BaseStream.ReadAsync(buffer, 0, buffer.Length));
        }

或者是事件处理程序被完全忽略,而是我在循环中调用 ReadAsync?

编辑:一旦解析,我将 1) 将数据发送到 TCP 服务器和 2) 将其写入 sq3lite 数据库。

【问题讨论】:

  • 我们在问题中有一个标签系统,你不需要在标题中添加标签。
  • 您能否详细说明您的问题?什么是“我的端口”?什么是“串行端口”?
  • @XiaominWu SerialPort 是 .NET 框架中用于与 COM 端口通信的类。 @user1957413,请说明您将如何使用这些数据,除非您解释您要做什么,否则我们无法告诉您如何操作。用一个示例更新您的问题,展示如何在没有 async/await 的情况下执行此操作,我们将向您展示如何使用异步 API。

标签: c# serial-port async-await


【解决方案1】:

Microsoft 已更新 API,可以实现相对简单的异步读写实现。请注意,您不会实现您似乎已经完成的同步事件处理程序,而是在您希望在 COM 端口上接收数据时调用此函数:

public async Task<Stream> ReceiveData()
{
    var buffer = new byte[4096];
    int readBytes = 0;
    SerialPort port = new SerialPort(/* ... */);
    using (MemoryStream memoryStream = new MemoryStream())
    {
        while ((readBytes = await port.BaseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
        {
            memoryStream.Write(buffer, 0, readBytes);
        }

        return memoryStream;
    }
}

这是另一种替代实现(请参阅http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport),作者在其中解释了 SerialPort DataReceivedBytesToRead 和其他 API 成员的问题。他没有使用 SerialPort API,因为他表示它的设计、实现和测试都很糟糕,他建议使用 BaseStream 来使用这种方法:

Action kickoffRead = null;
kickoffRead = delegate {
    port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar) {
        try {
            int actualLength = port.BaseStream.EndRead(ar);
            byte[] received = new byte[actualLength];
            Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
            raiseAppSerialDataEvent(received);
        }
        catch (IOException exc) {
            handleAppSerialError(exc);
        }
        kickoffRead();
    }, null);
};
kickoffRead();

请注意,我发现使用带有BaseStream 的 BCL 所获得的性能改进比使用 SerialPort API 好很多数量级。

【讨论】:

    猜你喜欢
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 2010-10-15
    • 2018-02-10
    • 2011-10-18
    相关资源
    最近更新 更多