由于我在几个小时内找不到合适的答案,所以我把它发到这里。
我有一个具有共享接口(IService)库的WPF/WCF应用程序和动态创建的代理(用CreateChannel创建)。主要的问题是代理没有被关闭/处理,我在第200次服务呼叫时得到了这个异常:
系统达到了油门“MaxConcurrentSession”的限制。此节流阀的极限设置为200。可以通过修改MaxConcurrentSessions元素中的属性'maxConcurrentSessions‘或修改行为ServiceThrottlingBehavior上的'MaxConcurrentSessions’属性来更改节流值。
有趣的是,同一个代理在BasicHttpBinding!中运行得很好。
NetNamedPipeBinding代理似乎没有被自动关闭和处理。下面是一些客户端代码片段。
// creation of ChannelFactory - only one for each service interface
public static ChannelFactory<T> CreateChannelFactory(string serviceAddress)
{
Binding binding = new NetNamedPipeBinding()
{
// setting quotas and timeouts
};
ChannelFactory<T> factory = new ChannelFactory<T>(binding, new EndpointAddress(serviceAddress));
factory.Endpoint.Behaviors.Add(new AuthenticationBehavior()); // custom IEndpointBehavior
foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 2147483647;
}
}
return factory;
}
public static T GetService()
{
// simplified - actually holding a collection of CFs and creating each factory only once
return ChannelFactoryHelper<T>.CreateChannelFactory(serviceAddress).CreateChannel();
}
// creation of the proxy - new for each WCF call
IService svc = ServiceHelper<IService>.GetService();
... // calling the service您可以看到,我没有使用“使用”语句,因为代理没有实现IDisposable。第一个问题是,我该怎么做?在客户端,我使用IService作为代理类型。如果我希望IService是IDisposable,我就必须在服务端上实现dispose方法--因为我的服务实现了IService。这似乎不符合逻辑-调用服务方法来处理该服务.
因为最好不要将服务调用的所有代码更改为“使用”:在不再使用时,有什么方法可以自动释放代理吗?为什么这不是自动完成的?请注意,我使用的是自定义IExtensionBehavior -这是原因吗?
任何帮助都将不胜感激。谢谢!
发布于 2013-08-15 15:29:22
首先,您会发现从CreateChannel方法返回的服务代理对象确实实现了IDisposable,因为IClientChannel是从IDisposable派生的。但是,您不应该使用标准的使用块来利用这一点,因为如果通道在使用时出现故障,则在结束括号中可能会出现难以诊断的异常。
也许您可能会发现以下模式的一些变体,与在包装器中显式地为每种服务代理类型实现IDisposable相比,这是一种改进。您可以在接受委托(Action<IService>)的泛型函数中实现该模式,以执行“调用服务”的操作。
IService svc;
try
{
// creation of the proxy - new for each WCF call
svc = ServiceHelper<IService>.GetService();
... // calling the service
myDelegateDoingStuffWithService(svc);
}
finally
{
try
{
((ICommunicationObject)svc).Close();
}
catch (CommunicationException ex)
{
((ICommunicationObject)svc).Abort();
}
}https://stackoverflow.com/questions/17084009
复制相似问题