我正在重构一个通过wcf进行进程间通信的大型程序员。因为客户端可以直接访问服务接口,所以使用了一个channel工厂来创建通道,因此不需要额外的客户端服务存根。通信由许多高频率请求的大消息组成(目前使用NetTcpBinding,我正在考虑切换到NetNamedPipeBinding)。
我的问题是关于创建/关闭通道与创建/关闭通道工厂之间的区别。更准确地说: channel工厂创建了一个通道。现在,关于单个请求:我是否应该创建和关闭通道工厂以及与单个请求相关的通道(参见方案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 ...实际的区别是什么?什么才是正确的方法呢?还有更好的选择吗?
发布于 2012-12-18 23:42:27
创建通道工厂可能需要70ms (在我正在开发的应用程序中)。创建通道(从现有的通道工厂创建通道相比之下相对较快)。如果您的客户端通常使用相同的凭据与主机通信,则应考虑为使用的每个服务接口缓存一个通道工厂。如果这样做,您将看到显著的性能改进。在你的问题中,这与你描述的第二个选项更密切相关。
Darin Damitrov在这里发表了一篇有趣的文章:
发布于 2012-02-16 23:18:10
根据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(),而Dispose()又调用Close(),则如果基础通道处于aborted状态,则会抛出异常。
发布于 2012-02-23 21:28:16
没有直接回答我最初的问题,但我已经看到在ChannelFactory上有一个静态的CreateChannel-method,人们可以用它来创建通道。我现在使用此方法来创建通道,因此,我不再需要处理channelfactory实例。因此,我在每次请求之前使用静态factorymethod创建clientchannel,然后关闭它(通道)。
https://stackoverflow.com/questions/9312799
复制相似问题