簡體   English   中英

正確實現 Async SerialPort Read

[英]Correct Implementation of Async SerialPort Read

我在這里閱讀了一些線程,建議將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 數據庫。

微軟已經更新了 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 好很多數量級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM