Я написал консольное приложение .net 4.0, которое периодически разговаривает с GSM-модемом, чтобы получить список полученных SMS-сообщений (это USB-модем, но код подключается к нему через драйвер последовательного порта и отправляет AT-команды - кстати, это модем Sierra Wireless, но я не могу его изменить, и у меня есть последний драйвер). Случается, что после некоторого периода времени (может быть, часов, может быть, дней) он просто перестает работать. Вот фрагмент журнала...
2012-04-17 23:07:31 DEBUG Modem Check (108) - Executing AT command 'AT+CPMS="ME"'...
2012-04-17 23:07:31 DEBUG Modem Check (108) - Finished executing 'AT+CPMS="ME"'
2012-04-17 23:07:31 DEBUG Modem Check (108) - Detaching event handlers for 'COM13'
2012-04-17 23:07:31 DEBUG Modem Check (108) - Disposing the SerialPort for 'COM13'
Это конец журнала - не более того, хотя я ожидаю увидеть хотя бы еще одно выражение, вот соответствующий код:
internal T Execute()
{
var modemPort = new SerialPort();
T ret;
try
{
modemPort.ErrorReceived += ModemPortErrorReceived;
modemPort.PortName = _descriptor.PortName;
modemPort.Handshake = Handshake.None;
modemPort.DataBits = 8;
modemPort.StopBits = StopBits.One;
modemPort.Parity = Parity.None;
modemPort.ReadTimeout = ReadTimeout;
modemPort.WriteTimeout = WriteTimeout;
modemPort.NewLine = "\r\n";
modemPort.BaudRate = _descriptor.Baud;
if (!modemPort.IsOpen)
{
modemPort.Open();
}
ret = _command.Execute(modemPort, _logger);
_logger.Debug("Detaching event handlers for '{0}'",
_descriptor.PortName);
modemPort.ErrorReceived -= ModemPortErrorReceived;
_logger.Debug("Disposing the SerialPort for '{0}'",
_descriptor.PortName);
}
catch (IOException ex)
{
_logger.Error(ex.Message);
throw new CommandException(
string.Format(CultureInfo.CurrentCulture,
ModemWrapperStrings.COMMAND_ERROR,
ex.Message),
ex);
}
catch (UnauthorizedAccessException ex)
{
_logger.Error(ex.Message);
throw new CommandException(
string.Format(CultureInfo.CurrentCulture,
ModemWrapperStrings.COMMAND_ERROR,
ex.Message),
ex);
}
finally
{
modemPort.Dispose();
_logger.Debug("Modem on port '{0}' disposed",
_descriptor.PortName);
}
return ret;
}
Как вы можете видеть, он зависает в методе Dispose класса SerialPort.
Я сделал некоторый Googling, и я пришел к этой проблеме: Serial Port Close Завершает приложение из этого потока: последовательный порт висит во время закрытия. Кажется, что консорциум закрывает порт в другом потоке, но это просто для приложения форм? В моем случае у меня есть простое консольное приложение, поэтому я не думаю, что он применяется (он просто работает в цикле в основном потоке). Я даже не уверен, что на самом деле это проблема (я чувствую, что вероятность того, что с драйвером последовательного порта связана с модемом, но я не знаю и, возможно, я несправедлив к модему). Насколько я понимаю, у меня есть три варианта:
- Закройте порт в другом потоке.
- Перед закрытием порта поставьте задержку
- Оставьте порт открытым навсегда
Мне не нравятся какие-либо из этих обходных решений, но я собираюсь оставить порт открытым и просто посмотреть, что происходит (у меня такое ощущение, что он просочится в память или что-то еще хуже, выложите некоторые другие проблемы с модемом, но, возможно, я я просто пессимистичен, и если это так, я мог бы уйти, закрыв его каждые 24 часа, скажем, и снова открыв его), поэтому мой вопрос...
Есть ли альтернатива с этим кодом, который может вызвать этот bevahior или есть альтернативный способ обхода описанного выше?