TcpClient 过早处置

TcpClient disposed prematurely

我有一个我似乎无法解决的问题,请帮忙。我创建了一个 class 来处理使用 TcpClient 的某些硬件的接口。我希望这个 class 在它被销毁之前向 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 的情况下发送。

Please tell me why an object which is clearly not yet out of scope is being disposed.

对象本身没有 "scope" 的概念。在您的程序结束时,TcpClient 您的 class 的实例都有资格完成 - 并且不能保证哪个将首先完成。听起来 TcpClient 首先完成(并且连接关闭),因此出现了问题。

最好的解决办法是一开始就不要依赖终结器——删除你自己的终结器(意识到如果客户端不调用 Dispose,连接将在某个时候关闭)并确保你 do 在程序终止时以有序的方式处理所有内容,假设它干净地终止(即通过你控制的某些路径)。