WCF服务代理的最佳实践是什么?

14

在使用WCF服务时,每次使用时创建新实例好还是创建一个实例并重复使用它更好?为什么这两种方法哪个更好?对于异步代理来说是否相同?

创建新的服务实例每次都会消耗一些系统资源,而且创建和销毁实例也需要一定的时间。因此,在高负载情况下,重复使用同一个实例可以提高性能并减少资源消耗。但是,如果服务实例持有状态(Stateful),则必须小心使用,并确保在使用之前正确初始化它们。
对于异步代理,最好采用与同步调用相同的方法来处理服务实例。重复使用异步代理实例可以提高性能并减少资源消耗。
4个回答

15

创建一个并重复使用它是否更好?

不要开始实现自己的池化实现。这已经在框架中完成了。WCF代理使用缓存的通道工厂。因此,创建新代理不会过度昂贵(但请参见Guy Starbuck有关会话和安全性的回复!)。

还要注意,代理在一定的空闲时间后会超时(默认为10分钟)。

如果您想要更明确的控制,可以考虑直接使用ChannelFactories和通道,而不是“易于使用,开箱即用”的ClientBase代理。

http://msdn.microsoft.com/en-us/library/ms734681.aspx

关于这个主题,必读的是: http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx


5
除了Guy Starbuck提到的事情之外,一个关键因素是你使用的安全模型(与会话要求相结合)-如果你不重复使用代理,就不能重复使用安全会话。
这意味着客户端必须在每次调用时进行身份验证,这是浪费的。
然而,如果你决定这就是你想要做的事情,请确保配置客户端不建立安全上下文(因为你永远不会使用它),这将为你节省几个往返服务器的时间 :-)

5

还有一个需要考虑的问题是通道故障。按照设计,WCF不允许在未处理异常发生后继续使用客户端代理。

IMyContract proxy = new MyContractClient( );
try
{
   proxy.MyMethod( );
}
catch
{}

//Throws CommunicationObjectFaultedException
proxy.MyMethod( );

3
这里有一个与.NET Remoting中的服务器激活对象相关的推论(这是一种被WCF替代的技术),它有两种模式,"单调用"(无状态)和"单例"(有状态)。
在WCF中采取的方法应该基于性能和扩展要求以及消费者的需求,以及服务器端的设计约束。
如果必须在服务调用之间保留状态,那么显然需要具有有状态实例,但如果不需要,则应该实现为静态,这样可以更好地进行扩展(例如,更容易进行负载平衡等)。

我认为Brian在询问客户端代理的重用。这与服务器端实例的生命周期无关。 - andrey.tsykunov
我的反对是出于与Andrey相同的原因。我不明白服务器端的InstanceManagement与客户端代理的生命周期有什么关系。也许你可以解释一下? - Kjetil Klaussen
你们两个都是对的,看起来我最初解释了问题与服务器生命周期有关,而不是客户端代理。我将继续保留我的答案作为讨论的一部分,因为其他人的回答中提到了它。 - Guy Starbuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接