c# – 什么时候在WCF服务中调用析构函数

c# – 什么时候在WCF服务中调用析构函数,第1张

概述我需要创建一个维护WCF会话的服务. 在构造函数中,我从数据库中读取数据,当会话结束时,我必须将其保存回来. 如果我理解正确,当我在客户端调用Close()时,会话结束(我的客户端ServiceClient是用SvcUtil.exe创建的). 当我测试它,我看到它有时被称为约. 10分钟,有时20分钟后,有时甚至没有. 那么析构函数什么时候叫? 服务 [ServiceBehavior(Instan 我需要创建一个维护WCF会话的服务.
在构造函数中,我从数据库中读取数据,当会话结束时,我必须将其保存回来.

如果我理解正确,当我在客户端调用Close()时,会话结束(我的客户端ServiceClIEnt是用SvcUtil.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>

客户

ServiceClIEnt serviceClIEnt = null;    try    {      serviceClIEnt = new ServiceClIEnt();      serviceClIEnt.Setname("Newname");      Console.Writeline("name set");    }    catch (Exception p_Exc)    {      Console.Writeline(p_Exc.Message);    }    finally    {      if (serviceClIEnt != null)      {        if (serviceClIEnt.State == CommunicationState.Faulted)        {          serviceClIEnt.Abort();        }        else        {          serviceClIEnt.Close();        }      }      Console.ReadKey();    }
解决方法 从 docs

The programmer has no control over when the destructor is called
because this is determined by the garbage collector. The garbage
collector checks for objects that are no longer being used by the
application. If it consIDers an object eligible for destruction,it
calls the destructor (if any) and reclaims the memory used to store
the object. Destructors are also called when the program exits.

您的实现有问题.要使用析构函数持久化数据.这是错误的,因为析构函数不能被确定性地调用,它们在单独的最终化队列中被处理.这意味着即使您已经销毁对象,也可能不会立即调用它的析构函数.

如何解决这个问题
删除析构函数,并使用Idisposable模式,将保存逻辑放入dispose.会话终止后,WCF将调用Idisposable.dispose

public class Service:IService,Idisposable{    public voID dispose()    {        //your save logic here    }}

编辑
Pls也看到这个答案的评论.我实际上同意,Idisposable不是数据库提交的适当位置,以前没有发生.除了评论中提供的解决方案,您可以使用explicit session demarcation

总结

以上是内存溢出为你收集整理的c# – 什么时候在WCF服务中调用析构函数全部内容,希望文章能够帮你解决c# – 什么时候在WCF服务中调用析构函数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1263650.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存