2012-02-16 29 views
1

我正在重构一个通过wcf进行进程间通信的大型程序。由于客户端可以直接访问服务接口,因此使用channelfactory创建通道,因此不需要额外的客户端服务存根。通信包含许多高频请求的大消息(目前使用NetTcpBinding,我正在考虑切换到NetNamedPipeBinding)。什么创建/关闭个人要求:ChannelFactory或创建频道?

我的问题是关于创建/关闭通道与创建/关闭通道工厂之间的区别。更确切地说:渠道工厂创建一个渠道。现在,就个别请求而言:我是否应该创建和关闭渠道工厂,并根据这个渠道与单个请求相关(请参阅解决方案2),还是在性能方面更安全/更好,只创建/关闭与个别请求有关的通道,并将通道工厂留在多个请求中(请参阅解决方案1)。

1)

//set up the channel factory right when I start the whole applicaton 
ChannelFactory<IMyService> cf = new ChannelFactory<IMyService>(); 

//call this trillion of times over time period of hours whenever I want to make a request to the service; channel factory stays open for the whole time 
try 
{ 
    IMyService myService = cf.CreateChannel(); 
    var returnedStuff = myService.DoStuff(); 
    ((IClientChannel)myService).Close(); 
} 
catch ... 

//close the channel factory when I stop the whole application 
cf.Close(); 

2)

//call this trillion of times over time period of hours whenever I want to make a request to the service 
try 
{ 
    ChannelFactory<IMyService> cf = new ChannelFactory<IMyService>(); 
    IMyService myService = cf.CreateChannel(); 
    var returnedStuff = myService.DoStuff(); 
    cf.Close(); 
} 
catch ... 

什么不同之实践?什么是正确的做法?还有更好的选择吗?

+0

你有什么用交谈的服务绑定? – 2012-02-16 14:18:07

+0

'ChannelFactory '实现'IDisposable',它的清理应该由'using'语句处理。 – 2012-02-16 14:21:56

+0

当前nettcp被用作绑定。我正在考虑切换到namedpipes,但考虑到当前的架构,这将是一个重大变化。 – user1182735 2012-02-16 14:28:30

回答

2

创建频道工厂最多可能需要70ms(在我正在开发的应用程序中)。 创建渠道(来自现有渠道工厂的比较速度相对较快)。如果您的客户端通常使用相同的凭证与主机进行通信,则应考虑为每个消耗的服务接口缓存一个通道因子。如果你这样做,你会看到显着的性能改进。在你的问题中,这更接近你描述的第二种选择。

达林Damitrov做了这样一个有趣的帖子在这里: -

creating WCF ChannelFactory<T>

0

根据http://www.danrigsby.com/blog/index.php/2008/02/26/dont-wrap-wcf-service-hosts-or-clients-in-a-using-statement/

,你应该这样做的方法是:

ChannelFactory<IMyService> channelFactory = null; 
try 
{ 
    channelFactory = 
     new ChannelFactory<IMyService>(); 
    channelFactory.Open(); 

    // Do work... 

    channelFactory.Close(); 
} 
catch (CommunicationException) 
{ 
    if (channelFactory != null) 
    { 
     channelFactory.Abort(); 
    } 
} 
catch (TimeoutException) 
{ 
    if (channelFactory != null) 
    { 
     channelFactory.Abort(); 
    } 
} 
catch (Exception) 
{ 
    if (channelFactory != null) 
    { 
     channelFactory.Abort(); 
    } 
    throw; 
} 

这背后的主要理由是,如果你打电话的ChannelFactory的Dispose(),这反过来调用Close(),它可以如果基础通道处于中止状态,则抛出异常。

+0

是的,这是关于使用语句与尝试和捕获。但我的问题是关闭通道与关闭通道工厂之间的区别。更确切地说:渠道工厂创建一个渠道。现在我有两件事情可以关闭:频道和频道工厂。关于个人请求:我是否应该关闭channelfactory并且在每个单独请求之后关闭这个频道,或者在性能方面更好/更安全/更好,只关闭频道并保持channelfactory打开。 – user1182735 2012-02-16 18:07:40

0

不是我原来的问题的direkt答案,但我已经看到,ChannelFactory上有静态的CreateChannel方法,可以用来创建通道。我现在使用这种方法来创建通道,结果,我不必再处理channelfactory实例。因此,我使用静态工厂方法在每个请求之前创建客户端通道,然后关闭它(通道)。

相关问题