我很难过。也许有人可以对我正在观察的WCF客户端行为有所了解。WCF使用,关闭和扩展
使用WCF示例,我已经开始使用WCF客户端/服务器通信的不同方法。在并行执行1M个测试请求的同时,我使用SysInternals TcpView监视打开的端口。现在,至少有4点不同的方式来调用客户端:
- 创建客户端,做你的事,并让GC收集它
- 在使用块创建客户端,不是做你的事
- 在使用块从原厂的客户渠道,不是做你的事
- 创建客户端或通道,但使用WCF Extensions做你的事
现在,据我所知,只有选择2-4,显式调用client.Close()。在执行期间,我看到很多端口都处于TIME_WAIT状态。由于依赖GC,我期望选项1是最糟糕的情况。然而,令我惊讶的是,它似乎是其中最清洁的,这意味着它不会留下任何滞留的港口。
我错过了什么?
UPDATE:源代码
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);
});
}
你错过了一些源代码...我们能否看到你的单元测试? – 2013-05-08 14:13:40
请参阅http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue - 使用块可能会导致WCF出现问题。 – TrueWill 2013-05-08 14:21:25
感谢您的链接,相当有趣的阅读,但它仍然不能解释为什么GC没有离开TIME_WAITs,但client.Close()。 – Darek 2013-05-08 14:29:44