[英]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 DataReceived
、 BytesToRead
和其他 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.