正确使用C#中的工厂和服务代理处理WCF服务
我有一部分程序在发生某些事情时向我发送电子邮件和/或推送消息到我的iphone。这是通过使用MSMQ调用两个独立的WCF服务完成的。我遵循this指南(模型4.0),以使其通用并且测试友好。我喜欢创建通用通道,但我的问题是代理和通道工厂是否真正关闭/处理正确,或者是否会在达到10000个用户环境时崩溃(最终它会这样)。该代码完全适用于我的50个用户测试环境。正确使用C#中的工厂和服务代理处理WCF服务
因此,请查看下面的代码:
服务代理
public class ServiceProxy<TChannel> : IServiceProxy<TChannel> where TChannel : ICommunicationObject
{
private readonly TChannel InnerChannel;
public ServiceProxy(TChannel innerChannel)
{
this.InnerChannel = innerChannel;
}
public void Execute(Action<TChannel> operation)
{
try
{
operation(InnerChannel);
InnerChannel.Close();
}
catch (CommunicationException)
{
InnerChannel.Abort();
}
catch (TimeoutException)
{
InnerChannel.Abort();
}
catch (Exception)
{
InnerChannel.Abort();
throw;
}
}
public TResult Execute<TResult>(Func<TChannel, TResult> operation)
{
TResult result = default(TResult);
try
{
result = operation(InnerChannel);
InnerChannel.Close();
}
catch (CommunicationException)
{
InnerChannel.Abort();
}
catch (TimeoutException)
{
InnerChannel.Abort();
}
catch (Exception)
{
InnerChannel.Abort();
throw;
}
return result;
}
}
服务代理工厂
public class ServiceProxyFactory : IServiceProxyFactory
{
public IServiceProxy<TChannel> GetProxy<TChannel>(string endpointName) where TChannel : ICommunicationObject
{
var factory = new ChannelFactory<TChannel>(endpointName);
return new ServiceProxy<TChannel>(factory.CreateChannel());
}
}
拨打服务电话(没有返回类型简单)
public class MessageSender : IMessageSender
{
private const string PushServiceEndpoint = "PushEndpointName";
private const string MailServiceEndpoint = "MailEndpointName";
private readonly IServiceProxyFactory ServiceProxyFactory;
public MessageSender()
{
ServiceProxyFactory = new ServiceProxyFactory();
}
public void NotifyMe(*some args*)
{
ServiceProxyFactory.GetProxy<MailServiceChannel>(MailServiceEndpoint)
.Execute(a => a.SendEmail(*some args*));
}
的问题是:
我应该后执行关闭用于ServiceProxy?
是否明智每次我打电话GetProxy()时创建的ChannelFactory,并应本的ChannelFactory然后如果是再次关闭?
是不是真的表现友善生成的每个调用ServiceProxy? (这对我来说真的很重,但也许有人可以证明我错了)。
我留下了接口,从这个职位,但他们真的很简单,这整个设置与代理和接口的作品真的很好用单元测试和集成测试。
我希望你们中的一些编码向导对此有意见,并将分享这一点。
在此先感谢!
主要性能影响创建了ChannelFactory
。
创建的ChannelFactory实例会带来一些开销,因为它涉及到以下操作: 构建ContractDescription树
Reflecting all of the required CLR types Constructing the channel stack Disposing of resources
https://msdn.microsoft.com/en-us/library/hh314046%28v=vs.110%29.aspx
WCF团队已经实现缓存ClientBase<TChannel>
类,很适合当你有自动生成的代理类。 由于您使用的是纯粹的ChannelFactory
,您必须小心在每次调用时创建工厂,以获得更好的性能。
一个好的解决方案是实现缓存ChannelFactory<TChannel>
你自己的(有a good idea如何做到这一点)。因此最后在ServiceProxyFactory
而不是new ChannelFactory<TChannel>(endpointName);
中,您应该使用像CachedChannelFactory<TChannel>.GetInstance()
这样的缓存实例。
编辑:还有一个很好的文章米歇尔·勒鲁布斯塔曼特书面解释时To Cache or Not to Cache
谢谢您的输入。你的“一个好主意”的链接是一个非常有趣的阅读。 虽然有一个问题:如果创建channelfactories是昂贵的操作,为什么不通过构造函数注入将ChannelFactory交给代理,然后为每个服务都有一个Service代理?通过这种方式,服务代理可以创建通道,执行某些操作并关闭通道... 这样,每个ServiceProxy都只有一个通道工厂,只能创建一次。 – ruNury
我认为,你的解决方案也是一个可行的选择,只要确保你控制你的实例的生命周期。 –