私は定期的にGSMモデムと通信して受信したSMSメッセージのリストを取得する.net 4.0コンソールアプリケーションを作成しました(これは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'
これでログは終わりです - 少なくとももう 1 つのステートメントが表示されると予想されますが、これ以上はありません。関連するコードは次のとおりです。
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 closed . 別のスレッドでポートを閉じるのが賢明なようですが、それはフォーム アプリケーションのためだけですか? 私の場合、単純なコンソール アプリケーションを持っているので、適用されないと思います (メイン スレッドのループで実行されているだけです)。それが実際にこの問題なのかどうかもわかりません (モデムのシリアル ポート ドライバに問題がある可能性が高いと思いますが、わかりませんし、おそらくモデムに対して不当な扱いをしているのかもしれません)。私が見る限り、私には3つの選択肢があります。
- 別のスレッドでポートを閉じます
- ポートを閉じる前に遅延を入れる
- ポートを永久に開いたままにします
私はこれらの回避策のどれもあまり好きではありませんが、ポートを開いたままにして、何が起こるかを見ようと考えています (メモリリークやさらに悪いことに、モデムの他の問題が明らかになるような気がしますが、私はただ悲観的です)もしそうなら、おそらく24時間ごとに閉じて、もう一度開くことで逃げることができるでしょう)それで私の質問は...
この動作を引き起こしている可能性のあるこのコードには別の問題がありますか、それとも上記で概説したものに対する別の回避策はありますか?