创建/关闭与单个请求相关的内容:ChannelFactory或创建的Channel

本文关键字:创建 ChannelFactory Channel 单个 请求 | 更新日期: 2023-09-27 18:24:55

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

我的问题是创建/关闭渠道与创建/关闭channelfactory之间的区别。更准确地说:channelfactory创建一个通道。现在,关于单个请求:我应该创建并关闭channelfactory,以及与单个请求相关的通道吗(请参阅解决方案2),还是只创建/关闭与单个请求有关的通道,并为多个请求打开channelfactory(请参阅解决方案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 ...

在实践上有什么不同?做这件事的正确方法是什么?还有更好的选择吗?

创建/关闭与单个请求相关的内容:ChannelFactory或创建的Channel

创建一个通道工厂可能需要长达70ms的时间(在我正在开发的应用程序中)。创建渠道(相比之下,从现有渠道工厂创建渠道相对较快)。如果客户端通常使用相同的凭据与主机通信,则应考虑为使用的每个服务接口缓存一个通道工厂。如果您这样做,您将看到显著的性能改进。在你的问题中,这将与你描述的第二种选择更密切相关。

Darin Damitrov在这里做了一个有趣的帖子:-

创建WCF ChannelFactory<T>

根据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(),而ChannelFactory又调用Close(),那么如果底层Channel处于中止状态,就会引发异常。

这不是我最初问题的直接答案,但我已经看到ChannelFactory上有一个静态的CreateChannel方法,可以用来创建通道。我现在使用这种方法来创建通道,因此,我不再需要处理channelfactory实例了。因此,我使用静态factorymethod在每个请求之前创建客户端通道,然后关闭它(通道)。