He escrito una aplicación de consola .net 4.0 que habla periódicamente con un módem GSM para obtener una lista de los mensajes SMS recibidos (es un módem USB pero el código se conecta a él a través de un puerto serie controlador y envía comandos AT - por cierto, es un módem Sierra Wireless pero no puedo cambiarlo y tengo el último controlador). Lo que sucede es que después de un período de tiempo (tal vez horas, tal vez días) simplemente deja de funcionar. Aquí es un fragmento de registro ...La clase SerialPort cuelga ocasionalmente Dispose
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'
Ese es el final del registro - nada más a pesar de que se puede esperar para ver al menos una declaración más, aquí está el código correspondiente:
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;
}
Como puede ver, se cuelga en el método Dispose de la clase SerialPort.
Hice algunos Google y llegué a este problema: Serial Port Close Hangs the application de este hilo: serial port hangs whilst closing. Lo consensuado parece ser cerrar el puerto con un hilo diferente, ¿es eso solo para una aplicación de formularios? En mi caso, tengo una aplicación de consola simple, así que no creo que se aplique (solo se ejecuta en un bucle en el hilo principal). Ni siquiera estoy seguro de que este sea realmente el problema (mi sensación es que es más probable que haya un problema con el controlador del puerto serie del módem, pero no sé y quizás estoy siendo injusto con el módem). Por lo que yo veo que tengo tres opciones:
- cerrar el puerto en un hilo diferente
- Poner en un retardo antes de cerrar el puerto
- dejar el puerto abierto para siempre
I realmente no me gusta ninguna de esas soluciones, pero estoy pensando en dejar el puerto abierto y solo ver qué pasa (tengo la sensación de que perderá memoria o algo peor, expondrá algún otro problema con el módem, pero tal vez solo soy pesimista y si ese es el caso, probablemente podría salirse con la suya cerrando cada 24 horas, s ay, y volver a abrirlo de nuevo) así que mi pregunta es ...
¿Hay algún otro problema con este código que pueda estar causando esta falla o hay una solución alternativa a lo que he descrito anteriormente?
¿Qué está pasando en el interior _command.Execute (..)? – PeskyGnat
¿Intentó utilizar la solución alternativa sugerida? Entiendo que todos los ejemplos son Winforms, pero [el artículo de consejos] (http://blogs.msdn.com/b/bclteam/archive/2006/10/10/top-5-serialport-tips-_5b00_kim-hamilton_5d00_. aspx) describe el tema muy claramente. Valdría la pena intentarlo al menos. –
Simplemente está enviando el comando y obteniendo una respuesta (en este caso, envió AT + CPMS = "ME") - sale bien de esa llamada, aunque recibí el mensaje de registro "Desechar el puerto serie para", así que pensé no era demasiado relevante lo que realmente hizo allí? ¿Hay algo que podría estar haciendo que daría lugar a la caída? – kmp