我编写了一个 .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;
}
如您所见,它挂在 SerialPort 类的 Dispose 方法上。
我做了一些谷歌搜索,我遇到了这个问题:Serial Port Close Hangs the application from this thread: serial port hangs while closing。共识似乎是在不同的线程中关闭端口,但这仅适用于表单应用程序吗?就我而言,我有一个简单的控制台应用程序,所以我认为它不适用(它只是在主线程的循环中运行)。我什至不确定这实际上是这个问题(我的感觉是调制解调器的串行端口驱动程序更有可能存在问题,但我不知道,也许我对调制解调器不公平)。在我看来,我有三个选择:
- 在不同的线程中关闭端口
- 在关闭港口之前延迟
- 让端口永远开放
我真的不喜欢这些解决方法,但我正在考虑让端口保持打开状态,然后看看会发生什么(我感觉它会泄漏内存或更糟,暴露调制解调器的其他问题,但也许我只是悲观如果是这种情况,我可能会每 24 小时关闭一次,然后重新打开一次)所以我的问题是......
此代码是否存在可能导致这种行为的替代问题,或者是否有替代我上面概述的解决方法?