gpt4 book ai didi

c# - WCF 使用、关闭和扩展

转载 作者:太空狗 更新时间:2023-10-29 23:46:31 24 4
gpt4 key购买 nike

我被难住了。也许有人可以阐明我正在观察的 WCF 客户端行为。

使用 WCF 示例,我开始使用不同的 WCF 客户端/服务器通信方法。在并行执行 1M 的测试请求时,我使用 SysInternals TcpView 来监视打开的端口。现在,至少有 4 种不同的方式来调用客户端:

  1. 创建客户端,做你的事,让 GC 收集它
  2. 在 using block 中创建客户端,然后做你的事
  3. 在 using block 中从工厂创建客户端 channel ,然后做你的事
  4. 创建客户端或 channel ,但使用 WCF Extensions做你的事

现在,据我所知,只有选项 2-4,显式调用 client.Close()。在执行期间,我看到许多端口处于 TIME_WAIT 状态。由于依赖 GC,我预计选项 1 是最坏的情况。然而,令我惊讶的是,它似乎是所有端口中最干净的,也就是说,它没有留下任何挥之不去的端口。

我错过了什么?

更新:源代码

    private static void RunClientWorse(ConcurrentBag<double> cb)
{
var client = new CalculatorClient();
client.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/ServiceModelSamples/service");
RunClientCommon(cb, client);
}

private static void RunClientBetter(ConcurrentBag<double> cb)
{
using (var client = new CalculatorClient())
{
client.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/ServiceModelSamples/service");
RunClientCommon(cb, client);
}
}

private static void RunClientBest(ConcurrentBag<double> cb)
{
const string Uri = "net.tcp://localhost:8000/ServiceModelSamples/service";
var address = new EndpointAddress(Uri);
//var binding = new NetTcpBinding("netTcpBinding_ICalculator");
using (var factory = new ChannelFactory<ICalculator>("netTcpBinding_ICalculator",address))
{
ICalculator client = factory.CreateChannel();
((IContextChannel)client).OperationTimeout = TimeSpan.FromSeconds(60);
RunClientCommon(cb, client);
}
}

private static void RunClientBestExt(ConcurrentBag<double> cb)
{
const string Uri = "net.tcp://localhost:8000/ServiceModelSamples/service";
var address = new EndpointAddress(Uri);
//var binding = new NetTcpBinding("netTcpBinding_ICalculator");
new ChannelFactory<ICalculator>("netTcpBinding_ICalculator", address).Using(
factory =>
{
ICalculator client = factory.CreateChannel();
((IContextChannel)client).OperationTimeout = TimeSpan.FromSeconds(60);
RunClientCommon(cb, client);
});
}

最佳答案

我想我已经弄明白了。 GC 不会调用 ClientBase 上的 Dispose。这就是连接不会处于 TIME_WAIT 状态的原因。所以我决定遵循相同的模式并创建一个新的 WCF 扩展:

    public static void UsingAbort<T>(this T client, Action<T> work)
where T : ICommunicationObject
{
try
{
work(client);
client.Abort();
}
catch (CommunicationException e)
{
Logger.Warn(e);
client.Abort();
}
catch (TimeoutException e)
{
Logger.Warn(e);
client.Abort();
}
catch (Exception e)
{
Logger.Warn(e);
client.Abort();
throw;
}
}
}

这样,在请求结束时,它将简单地中止连接而不是关闭它。

关于c# - WCF 使用、关闭和扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16442906/

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