0

I have a very interesting scenario where I would like a class to inform another entity it has been destroyed; however, its not doing what I want it too.

The Problem

The deconstructor, for some reason does not do what its supposed to do.

The Question

Why is the destructor not being invoked and make sure that it does do its necessary clean up.

The Code

So here we have the informer ~

class Connection 
{
   public const int Port = 50000;// Can be any range between 49152 and 65536

    //Teh Constructor
    public Boolean Connect()
    {
        //SetInformation
        Information.Id = 545;

        using (var WebServ = new ClientSDKSoapClient("ClientSDKSoap"))
        {
            ContinueConnection.WaitOne();
            WebServ.ClientLogin(Information);
        }
        return true;
    }

    ~Connection()
    {
        using (var WebServ = new ClientSDKSoapClient("ClientSDKSoap"))
        {
            WebServ.ClientLogout(Information);
        }
    }
}

Additional Information

I want the web service to record if the Connection Class is destroyed for any given reason. When the client is connecting, it works perfectly. The Web Service records every method called from it. If I call ClientLogout explicitly, it will work.

I am aware I can implement IDisposable; however, this object is not intended to be used within the lifetime of one method. In fact, its intended for use for the entire duration of the program and the failure of this object basically results in the failure of the entire project. (Although I suppose main IS a method...)

I need to release a network connection; however, its not in this program, its in another program and unless ClientLogout is called, it won't be released.

My Research

Microsoft says that you should use the deconstructor for the release of unmanaged resources making an explicit reference to network connections. This ones got my quite stumped.

4

2 回答 2

3

我认为你应该Dispose为你的 Connection 类实现一个模式,而不是依赖于一个晦涩的解​​构隐喻。这将是做到这一点的“规范”方式。

public class Connection : IDisposable  // <== Inherit from IDisposable interface
{
    public const int Port = 50000;// Can be any range between 49152 and 65536

    private SomeType webserv; // Use whatever real type is appropriate here.
    private Information information = new Information();  // or whatever

    // This is a real constructor.
    public Connection()
    {
        //SetInformation
        information.Id = 545;

        webServ = new ClientSDKSoapClient("ClientSDKSoap"))
        webserv.ContinueConnection.WaitOne();
        webServ.ClientLogin(information);
    }

    // Implement IDisposable interface
    public void Dispose()
    {
        webServ.ClientLogout(information);
    }
}

然后就这样使用它

using (var connection = new Connection())
{
    // Use the connection here.
}

using当您离开区块时,客户端将被注销。

于 2013-08-23T21:04:23.040 回答
1

微软说你应该使用解构器来释放非托管资源,明确引用网络连接。这让我很困惑。

这里的文档具有误导性。这实际上只是意味着您需要在对象继承链中的某个地方使用终结器,以确保适当地清理任何非托管资源。但是对于整个继承树,您只需要这个终结器一次,在非托管资源首次分配的级别。

例如,如果为数据访问层构建一个类来包装类型,则不需要析构函数或终结SqlConnection器,因为核心SqlConnection类型已经有一个。但是,您应该做的是实现IDisposable和编写代码以确保及时处理,因此您的终结器SqlConnection将被更快地调用,而不是更晚。但是,如果您要构建一个与 Sql Server、MySql、Oracle、Access 等竞争的全新数据库引擎,并为这个新的数据库引擎实现 ADO.Net 提供程序,那么需要为您的连接类型,因为尚不存在。

在这种情况下,ClientSDKSoaptype 已经有一个析构函数;你不需要写另一个。

于 2013-08-23T21:11:26.853 回答