I have written a .net 4.0 console application which periodically talks to a GSM modem to get a list of the receieved SMS messages (it is a USB modem but the code connects to it via a serial port driver and sends AT commands - incidentally it is a Sierra Wireless modem but I can't change it and I have the latest driver). What happens is that after some period of time (maybe hours, maybe days) it just stops working. Here is a log snippet...
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'
That is the end of the log - nothing more even though I would expect to see at least one more statement, here is the relevant code:
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 = "
";
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;
}
As you can see it hangs on the Dispose method of the SerialPort class.
I did some Googling and I came to this issue: Serial Port Close Hangs the application from this thread: serial port hangs whilst closing. The consensious seems to be to close the port in a different thread but is that just for a forms application? In my case I have a simple console application so I do not think it applies (it is just running in a loop in the main thread). I am not even sure it is actually this issue (my feeling is that it is more likely that there is an issue with the serial port driver from the modem but I don't know and perhaps I am being unfair to the modem). As far as I see it I have three choices:
- Close the port in a different thread
- Put in a delay before closing the port
- Leave the port open forever
I don't really like any of those workarounds but I am thinking of leaving the port open and just seeing what happens (I have this feeling that it will leak memory or worse, expose some other issue with the modem but maybe I am just pessimistic and if that is the case I could probably get away with closing it every 24 hours, say, and re-opening it again) so my question is...
Is there an alternative problem with this code that could be causing this bevahior or is there an alternative workaround to what I have outlined above?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…