我有一个问题,我似乎无法弄清楚,请帮忙。我创建了一个类来使用TcpClient处理某些HW的接口。我希望这个类在它被销毁之前向HW发送最后一个命令。
为了解决这个问题,我已经实现了IDisposable.Dispose来处理最后一个命令的发送,然后关闭连接。我也在析构函数中调用了Dispose。这是我在this article中阅读的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的情况下发送。
答案 0 :(得分:4)
请告诉我为什么一个明显尚未超出范围的物品正在处理中。
对象没有"范围"的概念。因此。在您的计划结束时,TcpClient
和您班级的实例都有资格进行最终确定 - 并且不保证最先确定哪一项。听起来好像TcpClient
正在最终确定(并且连接已关闭),因此问题就出现了。
最好的解决方法是首先不要依赖于最终确定 - 删除你自己的终结器(如果客户端没有调用Dispose
,则意识到连接将在某个时刻关闭)当程序终止时,确保你做以有序的方式处理所有事情,假设它干净地终止(即通过你控制的某个路径)。