完成对SerialPort.ReadLine()的调用

时间:2011-02-07 23:33:06

标签: c# call port readline abort

我正在编写一个程序来解析通过串口连接到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事件上实现逻辑,那是推荐的吗?最后,如果你能提出更好的建议,那就太好了。

提前感谢您提出任何意见或帮助。

1 个答案:

答案 0 :(得分:1)

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

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