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

时间:2012-02-16 14:14:44

标签: c# wcf channel channelfactory

我正在重构一个通过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 ...

有什么实际差异?做正确的方法是什么?还有更好的选择吗?

3 个答案:

答案 0 :(得分:2)

创建频道工厂最多可能需要70毫秒(在我正在处理的应用程序中)。 创建渠道(相比之下,来自现有渠道工厂的渠道相对较快)。如果您的客户端通常使用相同的凭据与主机通信,则应考虑为每个使用的服务接口缓存channelfactory。如果这样做,您将看到显着的性能改进。在您的问题中,这将与您描述的第二个选项更紧密相关。

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

creating WCF ChannelFactory<T>

答案 1 :(得分: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(),而ChannelFactory又调用Close(),如果底层Channel处于中止状态,则会抛出异常。

答案 2 :(得分:0)

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