Я пишу программу, которая анализирует ответы на AT-команды от GSM-модема, подключенного к ПК через последовательный порт. В этой программе у меня есть поток, который «слушает» все ответы на последовательном порту. Затем он может либо отправить ответ в очередь для потока, который запросил выполнение команды (которая блокируется, когда элемент помещен в эту очередь), либо он может сгенерировать событие, сигнализирующее о получении незапрошенного кода результата.
В настоящее время поток (метод) основан на методе 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, рекомендуется ли это? Наконец, если вы можете предложить что-то лучшее, это было бы здорово.
Заранее благодарю за любые комментарии или помощь людям.