我有一个似乎搞不懂的问题,请帮帮忙。我创建了一个类来使用TcpClient处理一些HW的接口。我希望这个类在HW被摧毁之前给它发送最后一条命令。
为了解决这个问题,我实现了IDisposable.Dispose来处理最后一个命令的发送,然后关闭连接。我也在破坏者中打了个电话来处理。当我在这篇文章中阅读它时,这是微软的推荐。我的代码如下:
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。
发布于 2015-01-20 16:46:51
请告诉我为什么要处理一个显然还没有超出范围的物体。
对象本身没有“范围”的概念。在您的程序结束时,TcpClient和类的实例都有资格完成--并且没有任何保证将首先完成。听起来TcpClient已经完成(并且连接已经关闭),这就是问题所在。
最好的解决方法是,首先不要依赖于终结--删除您自己的终结器(意识到如果客户端不调用Dispose,连接将在某个时候关闭),并确保在程序终止时以有序的方式处理所有事情,前提是程序完全终止(即通过您控制的某些路径)。
https://stackoverflow.com/questions/28050703
复制相似问题