2

我正在编写一个程序来解析来自通过串行端口连接到 PC 的 GSM 调制解调器对 AT 命令的回复。在这个程序中,我有一个线程“监听”串行端口上的所有回复。然后它可以将响应发送到请求执行命令的线程的队列(当项目发布到该队列时该线程被阻塞),或者它可以生成一个事件来表示接收到未经请求的结果代码。

目前线程(方法)基于 SerialPort.ReadLine 方法,是我编写的名为“GsmModem”的类的一部分。当调用 GsmModem.Close() 方法时。我需要通知“侦听器”线程完成并等待它终止,然后关闭我的串行端口。我当前的代码不是很优雅,因为它依赖于串口的超时异常。线程随着 serialPort.ReadLine() 引发超时异常并检查 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 事件上实现逻辑吗,是否推荐?最后,如果您能提出更好的建议,那就太好了。

提前感谢您的任何评论或帮助。

4

1 回答 1

1

我建议使用该SerialPort.DataReceived事件。这意味着要为串行数据维护自己的缓冲区,但这并不是很复杂。这样做,您将不必维护您的侦听器线程。相反,当您准备好关闭串行端口时,只需移除DataReceived委托并关闭端口即可。

SerialPort.ErrorReceived处理事件也是一个好主意。您可能已经在这样做了。

于 2011-02-10T04:16:57.550 回答