私には理解できない問題があります。助けてください。TcpClient を使用して一部のハードウェアへのインターフェイスを処理するクラスを作成しました。このクラスが破壊される前に、最後のコマンドを HW に送信する必要があります。
これを解決するために、IDisposable.Dispose を実装して最後のコマンドの送信を処理し、接続を閉じました。また、デストラクタで Dispose を呼び出しました。これは、この記事で読んだ Microsoft の推奨事項です。私のコードは次のとおりです。
class MyHWInterface : IDisposable
{
~MyHWInterface()
{
Dispose();
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
CloseConnection();
disposed = true;
}
}
private System.Net.Sockets.TcpClient Port = new System.Net.Sockets.TcpClient();
public bool OpenConnection()
{
...
}
private bool SendCommand(string command)
{
var strm = Port.GetStream(); // This throws the exception Cannot access disposed object!
var w = new System.IO.StreamWriter(strm, System.Text.Encoding.ASCII);
var r = new System.IO.StreamReader(strm, System.Text.Encoding.ASCII);
w.WriteLine(command);
w.Flush();
string l = r.ReadLine();
return l == "OK";
}
internal void CloseConnection()
{
try
{
SendCommand("power down now");
}
catch
{
}
finally
{
Port.Close();
}
}
}
私の問題は次のとおりです。プログラムが終了すると、 MyHWInterface のオブジェクトがスコープ外になり、ガベージコレクションが発生します。最後のコマンドを送信しようとするデストラクタが呼び出されますが、何らかの形で TcpClient が既に破棄されているために失敗します。
明らかにまだ範囲外ではないオブジェクトが破棄されている理由を教えてください。そして、Dispose を明示的に呼び出さずに最後のコマンドが常に送信されるようにする方法を教えてください。