gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:39:33 25 4
gpt4 key购买 nike

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

如果我理解正确,当我在客户端调用 Close() 时 session 结束(我的客户端 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 中。一旦 session 终止,WCF 将调用 IDisposable.Dispose

public class Service:IService, IDisposable
{
public void Dispose()
{
//your save logic here
}
}

编辑
另请参阅对此答案的评论。我实际上同意 IDisposable 不是数据库提交的合适位置,我以前没有想到。除了评论中提供的解决方案之外,您还可以使用 explicit session demarcation

关于c# - 什么时候在 WCF 服务中调用析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7295198/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com