gpt4 book ai didi

.net - 未使用 InstanceContectMode = PerSession 调用 WCF Dispose()

转载 作者:行者123 更新时间:2023-12-04 14:03:50 25 4
gpt4 key购买 nike

在 PerSession 中,如何让服务上的 Dispose() 触发?在下面的代码中 Dispose() 没有被调用。当我调用 .Close() 或让 session 超时时都不会。

如果我将服务更改为 PerCall Dispose() 会被调用(每个方法调用)。使用 PerSession 我得到一个 session (用 serviceStartTime 测试)。

服务

[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]
public class MagicEightBallService : IEightBall, IDisposable
{
private DateTime serviceStartTime;
public void Dispose()
{
Console.WriteLine("Eightball dispose ... " + OperationContext.Current.SessionId.ToString());
}
public MagicEightBallService()
{
serviceStartTime = DateTime.Now;
Console.WriteLine("Eightball awaits your question " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
}
public string ObtainAnswerToQuestion(string userQuestion)
{
return "maybe " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString();
}

客户
    using (EightBallClient ball = new EightBallClient())
{
while (true)
{
Console.Write("Your question: ");
string question = Console.ReadLine();
if (string.IsNullOrEmpty(question)) break;
try
{
string answer = ball.ObtainAnswerToQuestion(question);
Console.WriteLine("8-ball says: {0}", answer);
}
catch (Exception Ex)
{
Console.WriteLine("ball.ObtainAnswerToQuestion exception " + Ex.Message);
}
}
ball.Close();
}

服务-契约(Contract)
[ServiceContract (SessionMode = SessionMode.Required)]
public interface IEightBall
{
[OperationContract]
string ObtainAnswerToQuestion(string userQuestion);

[OperationContract]
sDoc GetSdoc(int sID);

DateTime CurDateTime();
}

主持人
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ISampleService"
closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="Message" />
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="true" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MajicEightBallServiceLib.MagicEightBallService"
behaviorConfiguration="EightBallServiceMEXBehavior" >
<endpoint address=""
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ISampleService"
contract="MajicEightBallServiceLib.IEightBall">
</endpoint>
<endpoint address="mex"
binding ="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/MagicEightBallService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="EightBallServiceMEXBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

namespace MagicEightBallServiceHost
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("**** Console Based WCF Host *****");

using (ServiceHost serviceHost = new ServiceHost(typeof(MagicEightBallService)))
{
serviceHost.Open();
Console.WriteLine("The service is running");
Console.ReadLine();
}
}
}
}

最佳答案

Dispose()方法将被解雇。唯一的问题是“什么时候?”。

该问题的答案取决于服务配置。

有几种可能的情况:

  • 绑定(bind)不支持 session
  • 正常 session
  • 可靠 session
  • Dispose()PerSession 的 session 关闭时触发上下文模式。所以我们需要检查 session 在不同场景下的存活时间。

    对于某些配置(例如默认 BasicHttpBinding ), session 根本不会启动。如果是无 session 配置 PerCallPerSession上下文模式和 Dispose 没有区别方法将在您的 main 方法执行后很快被调用。

    Session启用它可以由客户端或超时显式关闭。通常它是由客户端控制的。客户端在第一次调用服务之前启动 session ,并在客户端对象关闭时关闭它。
    ServiceClient proxy = new ServiceClient();
    Console.WriteLine(proxy.GetData(123));
    proxy.Close();
    proxy.Close()上面的方法关闭服务器中的 session ,然后执行 Dispose() .

    session 管理是一个很大的性能驱动因素,因为它需要在客户端和服务器之间执行额外的调用。

    所以通常 Dispose当客户端想要关闭 session 时将被调用。

    如果客户端由于任何原因没有关闭 session ,它将在一段时间后被服务主机关闭。该期间由 Binding.ReceiveTimeout 控制。属性(property)。
    该属性的默认值为 10 分钟。

    如果在 10 分钟内没有人向具有特定 session ID 的服务器发送请求, session 将被关闭并( Dispose() 被触发)。
    这个默认超时可以通过设置 receiveTimeout 来改变。到 web.config 中的一些较短的值。
    <wsHttpBinding>
    <binding name="wsHttpEndpointBinding" receiveTimeout="00:00:05">
    </binding>
    </wsHttpBinding>

    ReliableSession.InactivityTimeout启用可靠 session 时还会检查。它也默认为 10 分钟。

    它在自托管和 IIS 托管服务中按预期工作。

    尝试如下更新您的客户端代码进行测试:
    using (EightBallClient ball = new EightBallClient())
    {
    ball.ObtainAnswerToQuestion("test");
    ball.Close();
    }

    关于.net - 未使用 InstanceContectMode = PerSession 调用 WCF Dispose(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11038327/

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