我正在编写一个程序来解析通过串口连接到PC的GSM调制解调器对AT命令的回复。在这个程序中,我有一个线程“侦听”串口上的所有回复。然后,它可以将响应发送到请求执行命令的线程的队列(在项目发布到此队列时被阻止)或者它可以生成一个事件来表示接收到非请求结果代码。 / p>
目前,线程(方法)基于SerialPort.ReadLine方法,并且是我编写的名为“GsmModem”的类的一部分。调用GsmModem.Close()方法时。我需要通知“监听器”线程完成并等待它终止然后关闭我的串口。我当前的代码不是很优雅,因为它依赖于串口的超时异常。该线程使用serialPort.ReadLine()抛出Timeout异常并检查ManualResetEvent标志。我真的想避免这种情况。
如果可以中止对SerialPort.Readline()的调用,我已经到处寻找,但唯一的解决方案似乎是超时异常。
其他可能的方法是使用 SerialPort.DataReceived 事件来处理数据,并在收到新行时将其排队,或者在收到未经请求的响应时引发新事件(我不知道)如果这是一个好主意)。
实际代码如下所示:
private void ModemListenerThread()
{
if (this._serialPort.IsOpen)
{
//Execute the thread wile we don't receive the "endThreadSignal"
while(!this._endThreadEvent.WaitOne(0))
{
// Catch TimeoutException and spin checking for the ManualResetEvent
try
{
// Read line
string line = this._serialPort.ReadLine();
if (String.IsNullOrWhiteSpace(line))
continue;
//Check if no command was sent (not definitive code)
if (_modemIsIdle)
this.OnUnsolicitedResponse(new EventArgs());
else
{
//Enqueue as reply to command()
lock ((this._itemQueue as ICollection).SyncRoot)
{
_itemQueue.Enqueue(line);
this._itemPostedEvent.Set();
}
}
}
//Timeout is necessary to avoid the thread to block indefinitely
catch (TimeoutException ex)
{
continue;
}
}
}
}
任何有关如何实施回复处理的建议都将受到赞赏。我的主要问题是:是否可以中止对readline的调用?如果没有,我可以在SerialPort.DataReceved事件上实现逻辑,那是推荐的吗?最后,如果你能提出更好的建议,那就太好了。
提前感谢您提出任何意见或帮助。
答案 0 :(得分:1)
我建议使用SerialPort.DataReceived
事件。这将意味着为串行数据维护自己的缓冲区,但这并不复杂。这样做,你不必维护你的监听线程。相反,当您准备关闭串行端口时,只需删除DataReceived
委托并关闭端口。
处理SerialPort.ErrorReceived
事件也是一个好主意。你可能已经这样做了。