WCF - 通道工厂与客户群

Posted

技术标签:

【中文标题】WCF - 通道工厂与客户群【英文标题】:WCF - channel factory vs client base 【发布时间】:2011-12-08 16:05:09 【问题描述】:

我是 WCF 的新手。最初我创建了一个 WCF 服务并使用生成的客户端代理来使用来自客户端的服务。因此,每当我对服务执行一些操作时,一切都会按顺序执行,因为我同步调用操作。我将并发模式更改为多个,但操作仍然同步发生。然后我为我的操作生成异步方法并使用开始/结束模式,因此我猜想“释放”通道并让操作并行/异步发生,从而增加我的应用程序的吞吐量。

然后我使用ChannelFactory 创建了一个频道并执行了客户端和服务器可以共享合约的操作(同一个项目)。但是IClientChannel 只提供BeginOpen/EndOpen/BeignClose/EndClose。它没有ClientBaseBeginOperation/EndOperation 方法。所以基本上我不能在通道上异步执行操作来释放空间,以便我可以使用通道执行其他操作。

我只是为每个操作创建了通道,它解决了问题

所以我的问题是:

    哪个更好 (ClientBase vs. ChannelFactory) w.r.t 适合我的场景,特别是我想使用多个线程同时对服务对象执行多个操作

    是否建议为每个操作创建一个通道?

    事实上,我认为我们在两个端点(客户端/服务)之间只能有一个通道。但我可以创建任意数量的频道。例如:我能够创建通道的 Int16.MaxValue。所以不确定这方面的限制和建议。

    Service[] channels = new IService[Int16.MaxValue];
    
    for(int i = 0; i<Int16.MaxValue; i++)
    
       channels[i] = factory.CreateChannel();
    
    

所以基本上你能告诉我有关频道的基本知识和推荐和技巧等...等..:)

【问题讨论】:

【参考方案1】:

ClientBaseChannelFactory&lt;T&gt; 之间使用异步是有区别的。基本上ClientBase 使用的是事件驱动的异步模型。

我在工作中开发的一个应用程序中广泛使用了ChannelFactory&lt;T&gt;,主要是因为合约在应用程序的公共库中可用,我不喜欢使用添加服务参考。我在创建时缓存 ChannelFactory 的每个唯一实例,然后当我需要调用操作时,我将从该实例打开一个通信通道,进行调用,然后关闭通信通道。

WCF 的大部分启动成本用于创建客户端,这样您只需在应用程序的生命周期内支付一次 - 创建通信渠道是微不足道的。

有关ClientBaseChannelFactory&lt;T&gt; 的异步的更多信息,请参阅:

How to: Call WCF Service Operations Asynchronously

How to: Call Operations Asynchronously Using a Channel Factory

【讨论】:

谢谢蒂姆。是的,我也在做几乎相同的事情。为每个操作创建一个新的通信通道并关闭它。我查看了链接,但我仍然有一些问题。 1. 推荐多少频道? 2. 要使用通道工厂同步执行操作,我们只需将 BeginOp/EndOp 方法添加到通道接口。剩下的一切都由 WCF 处理——换句话说,svcutil util 生成了太多我们不感兴趣的代码。我们只对接口定义感兴趣,让 WCF 完成繁重的工作。如果是,这很酷。\ 除了以上问题还有其他问题吗? @Dreamer - 我认为没有推荐的频道数量。如果您有很多客户端,您可能会遇到并发连接问题,但您可以在配置中进行调整。至于你的第二个问题,我还没有在 WCF 中做任何异步操作(我们正准备在下一次工作中这样做),但我认为只要接口正确,你应该没问题。 感谢蒂姆。顺便说一句,你有没有机会看看我的另一个问题(WCF - 基于标签/有条件地为单个客户端创建多个服务实例(不基于 percall)

以上是关于WCF - 通道工厂与客户群的主要内容,如果未能解决你的问题,请参考以下文章

使用通道工厂而不是使用代理或添加服务引用来使用外部 WCF 服务

老老实实学WCF] 第五篇 再探通信--ClientBase

WIF(使用 Thinktecture Identity Server)和双工 WCF 通道

WCF - 长时间打开通道是不好的做法吗?

WCF 回调通道出现故障

在 Mono Mac 上调用 WCF 客户端通道上的 Close() 超时,但在 Windows 上有效