gpt4 book ai didi

c# - 串行端口异步读取(非阻塞)+ 线程

转载 作者:太空宇宙 更新时间:2023-11-03 22:01:01 25 4
gpt4 key购买 nike

好吧,在过去的 4 天里,我一直在努力使用 C# 中的这个 SerialPort 控件,但没有令人满意的结果。让我解释一下:

我有一个设备(Arduino UNO 板)与模拟秤(简单请求/响应模式)的 c# 程序通信,该设备发送一个由 3 个字节组成的命令序列(要求称重):CHR(27 )+P+CHR(13) 所以模拟器以模拟重量响应(我已经弄清了设备如何捕捉和解析这个重量所以这不再是问题)。使用 DataReceive 事件似乎我正在使用 Serialport.Read() 丢失数据,所以到目前为止我浪费了这种方法。模拟器必须始终监听所述序列。字节数并且必须有一个 GUI。我知道为此我必须使用线程以防止 GUI 被锁定(也许是后台 worker ?)和一种在(现在)这两个线程之间共享的缓冲区并防止线程同时读/写到缓冲区(我需要状态机吗?)(我寻求帮助,因为我不知道这是一个好方法还是我的假设是错误的,或者是否有更简单的方法来解决这个问题)所以我我正在寻求建议和(幸运的是)代码片段,或者如果您曾面临开发类似应用程序的问题,那么您是如何解决它的。

如果需要进一步说明,我可以提供到目前为止我所做的代码。希望你能阐明这一点。

提前致谢。

更新 1


这是我目前的代码:

ConcurrentQueue<byte> queue = new ConcurrentQueue<byte>();
....
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
bool listening = true;
while(listening)
{
if(serialPort.BytesToRead > 0)
{
byte b = (byte)serialPort.ReadByte();
queue.Enqueue(b);
}
}
}

因此,由于命令必须以字符 13(ASCII 中的 CR)结尾:

public string GetCommand()
{
string ret = "";
byte[] ba = new byte[1];
byte b = (byte)' ';

while(b!=13)
{
if(queue.TryDequeue(out b))
{
ba[0] = b;
ret += ASCIIEncoding.ASCII.GetString([ba]);
}
}
return ret;
}

为了测试这个 GetCommand() 方法,我在 buton_click 事件中从主 ui 线程调用它,但它挂起了应用程序,我是否需要创建另一个线程来调用 GetCommand() ?

最佳答案

这适用于少量数据。但是如果数据更大,比如传递一些 http 信息,那么队列大小可能就不够用了。所以我认为你应该使用非阻塞类型的架构。

关于c# - 串行端口异步读取(非阻塞)+ 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10117861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com