Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务中何时调用析构函数_C#_Wcf_Session_Destructor - Fatal编程技术网

C# WCF服务中何时调用析构函数

C# WCF服务中何时调用析构函数,c#,wcf,session,destructor,C#,Wcf,Session,Destructor,我需要创建一个服务来维护WCF会话。 在构造函数中,我从数据库中读取数据,当会话结束时,我必须将其保存回去 如果我理解正确,则在客户端上调用Close()时会话结束(我的客户端ServiceClient是使用svcuti.exe创建的) 当我测试它时,我发现它有时在大约10分钟后调用,有时在20分钟后调用,有时根本不调用 那么什么时候调用析构函数呢 服务 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSessio

我需要创建一个服务来维护WCF会话。 在构造函数中,我从数据库中读取数据,当会话结束时,我必须将其保存回去

如果我理解正确,则在客户端上调用Close()时会话结束(我的客户端ServiceClient是使用svcuti.exe创建的)

当我测试它时,我发现它有时在大约10分钟后调用,有时在20分钟后调用,有时根本不调用

那么什么时候调用析构函数呢

服务

   [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
    }
}