为什么Destructor没有被调用
本文关键字:调用 Destructor 为什么 | 更新日期: 2023-09-27 18:29:01
我有一个非常有趣的场景,我希望一个类通知另一个实体它已经被销毁;然而,它也没有做我想做的事。
问题
由于某种原因,解构者没有做它应该做的事
问题
为什么没有调用析构函数,并确保它确实进行了必要的清理。
守则
所以我们有了告密者~
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);
}
}
}
附加信息
我希望web服务记录连接类是否因任何给定原因而被破坏。当客户端连接时,它可以完美地工作。Web服务记录从它调用的每个方法。如果我显式调用ClientLogout,它就会工作。
我知道我可以实现IDisposable;但是,该对象不打算在一个方法的生命周期内使用。事实上,它打算在整个项目期间使用,而这个对象的失败基本上导致了整个项目的失败。(虽然我认为主要是一种方法…)
我需要释放一个网络连接;但是,它不在这个程序中,而是在另一个程序中,除非调用ClientLogout,否则它不会被释放。
我的研究
微软表示,你应该使用解构器来发布明确引用网络连接的非托管资源。这些让我很为难。
我认为应该为Connection类实现Dispose
模式,而不是依赖于晦涩的解构隐喻。这将是"规范"的方式来做到这一点
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
块时,客户端将被注销。
微软表示,你应该使用解构器来发布明确引用网络连接的非托管资源。这些让我很为难。
这里的文件具有误导性。这实际上只是意味着您需要在对象继承链中的某个位置使用终结器,以确保适当地清理任何非托管资源。但是,对于整个继承树,在首次分配非托管资源的级别,您只需要一次这个终结器。
例如,如果为数据访问层构建一个类来包装SqlConnection
类型,则不需要析构函数或终结器,因为核心SqlConnection
类型已经有了一个。不过,应该实现IDisposable
并编写代码以确保及时处理,因此SqlConnection
上的终结器将尽快被调用。但是,如果您要构建一个与SqlServer、MySql、Oracle、Access等竞争的全新数据库引擎,并为该新数据库引擎实现ADO.Net提供程序,则需要为您的连接类型编写终结器,因为目前还不存在。
在这种情况下,ClientSDKSoap
类型已经有一个析构函数;你不需要再写一篇。