1

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

我的问题是关于创建/关闭频道与创建/关闭频道工厂之间的区别。更准确地说:channelfactory 创建了一个通道。现在,关于单个请求:我应该创建和关闭 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 ...

有什么实际区别?正确的方法是什么?还有更好的选择吗?

4

3 回答 3

2

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

达林·达米特洛夫(Darin Damitrov)在这里发表了一篇有趣的文章:-

创建 WCF ChannelFactory<T>

于 2012-12-18T15:42:27.017 回答
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(),如果底层 Channel 处于中止状态,则可能会引发异常。

于 2012-02-16T15:18:09.513 回答
0

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

于 2012-02-23T13:28:16.340 回答