C# WCF服务中何时调用析构函数
我需要创建一个服务来维护WCF会话。 在构造函数中,我从数据库中读取数据,当会话结束时,我必须将其保存回去 如果我理解正确,则在客户端上调用Close()时会话结束(我的客户端ServiceClient是使用svcuti.exe创建的) 当我测试它时,我发现它有时在大约10分钟后调用,有时在20分钟后调用,有时根本不调用 那么什么时候调用析构函数呢 服务C# WCF服务中何时调用析构函数,c#,wcf,session,destructor,C#,Wcf,Session,Destructor,我需要创建一个服务来维护WCF会话。 在构造函数中,我从数据库中读取数据,当会话结束时,我必须将其保存回去 如果我理解正确,则在客户端上调用Close()时会话结束(我的客户端ServiceClient是使用svcuti.exe创建的) 当我测试它时,我发现它有时在大约10分钟后调用,有时在20分钟后调用,有时根本不调用 那么什么时候调用析构函数呢 服务 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSessio
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service:IService
{
private User m_User = null;
public Service()
{
m_User = User.LoadFromDB();
}
~Service()
{
m_User.SaveToDB();
}
public void SetName(string p_Name)
{
m_User.Name = p_Name;
}
}
Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<sessionState timeout="2" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="Karatasi.Services.B2C" behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:19401/B2C.svc"/>
</baseAddresses>
</host>
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="test"
contract="Karatasi.Services.IB2C"
/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="test" receiveTimeout="00:01:00" >
<reliableSession enabled="true" ordered="false" inactivityTimeout="00:01:00"/>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
从
程序员无法控制何时调用析构函数
因为这是由垃圾收集器决定的。垃圾
收集器将检查不再由服务器使用的对象
应用如果它认为某个对象符合销毁条件,则
调用析构函数(如果有)并回收用于存储的内存
物体。当程序退出时,也会调用析构函数
您的实现存在问题。要持久化数据,请使用析构函数。这是错误的,因为不能确定地调用析构函数,它们在单独的终结队列中处理。这意味着,即使您已销毁了对象,也可能不会立即调用其析构函数
如何解决此问题移除析构函数并改用IDisposable模式,将保存逻辑放入Dispose。一旦会话终止,WCF将调用IDisposable.Dispose
public class Service:IService, IDisposable
{
public void Dispose()
{
//your save logic here
}
}
编辑请看对这个答案的评论。实际上,我同意,
IDisposable
不是数据库提交的合适位置,我以前从未想到过。除评论中提供的解决方案外,您还可以使用No!不要把它放在IDisposable.Dispose中<代码>IDisposable.Dispose用于清理托管资源。保存到数据库不是清除托管资源。这违背了此接口的公认和预期用途。对数据库进行SetName
提交更改,或者在服务commit
上提供另一种方法。另外,在C#中,我们称之为“终结器”。是的,在这个主题上有很多困惑。首先,这是完全错误的服务设计。
public class Service:IService, IDisposable
{
public void Dispose()
{
//your save logic here
}
}