通过共享通道并发 WCF 调用

Posted

技术标签:

【中文标题】通过共享通道并发 WCF 调用【英文标题】:Concurrent WCF calls via shared channel 【发布时间】:2011-02-03 19:40:14 【问题描述】:

我有一个将调用转发到应用层的 Web 层。 Web 层使用共享的缓存通道来执行此操作。有问题的应用层服务是无状态的并且启用了并发性。

但它们不会同时被调用。

如果我更改 Web 层以在每次调用时创建一个新通道,那么我确实会在应用程序层上获得并发调用。但我想避免这种成本,因为它在我的场景中在功能上是不必要的。我没有会话状态,也不需要每次都重新验证调用者。我知道创建通道工厂比创建通道要昂贵得多,但如果可能的话,我仍然希望避免这种成本。

我在 MSDN 上找到了this article,上面写着:

虽然频道和客户端由 通道是线程安全的,它们 可能不支持写作超过 一条消息同时发送到线路。 如果您要发送大邮件, 特别是如果流式传输,发送 操作可能会阻塞等待 另一个发送完成。

首先,我没有发送大消息(只是很多小消息,因为我正在进行负载测试),但仍然看到阻塞行为。其次,这是相当开放且无用的文档。它说他们“可能不”支持编写多条消息,但没有解释他们支持并发消息的场景。

有人能解释一下吗?

附录:我也在考虑创建一个网络服务器用来满足请求的通道池。但同样,我认为没有理由阻止我现有的方法,如果可能的话,我宁愿避免复杂性。

【问题讨论】:

【参考方案1】:

您可以缓存 WCF 代理,但仍为每个服务调用创建一个通道 - 这将确保并发性,与从头开始创建通道相比成本不是很高,并且无需为每个调用重新验证。这在 Wenlong Dong 的博客 -"Performance Improvement for WCF Client Proxy Creation in .NET 3.5 and Best Practices" 上进行了解释(比 MSDN 更好的 WCF 信息和指导来源)。

【讨论】:

+1 根据我的问题中的附录,池化是我的备份方法。但是,我仍然想知道在什么情况下可以成功地与并发共享单个代理。除非我错过了什么,否则该博客文章不会涵盖这些情况。【参考方案2】:

经过一番折腾,这一切都归结为这样一个事实,即在使用之前我没有在频道上明确调用Open。显然,隐含的Open 在某些情况下会阻止并发。

【讨论】:

太棒了。能否请您添加参考? 说实话,我想我没有。有各种帖子,例如blogs.msdn.com/b/mjm/archive/2006/11/13/auto-open-part-1.aspx,为我提供了提示,但我还没有看到明确显示自动打开如何排除并发调用的帖子。我记得当时打算写自己的帖子,但一直没来得及做。我会将它添加到我的队列中,并在它启动时发回这里。 您能否发布一个如何创建频道的代码示例?我正在为同样的问题苦苦挣扎,在 ChannelFactory 上调用 Open() 对我没有帮助。 我想强调一些 场景,因为事实证明这取决于您使用的绑定。使用 BasicHttpBinding 时,它确实有效,但使用 NetNamedPipe 绑定时,所有调用仍然是同步的。【参考方案3】:

仅出于完整性考虑:这是一篇博客文章,解释了在未显式打开通道时观察到的请求序列化行为:

http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

【讨论】:

以上是关于通过共享通道并发 WCF 调用的主要内容,如果未能解决你的问题,请参考以下文章

go语言--通道

重复调用的 WCF 通道生命周期

在 Service Fabric 中通过 HTTPS 调用 WCF:请求被中止:无法创建 SSL/TLS 安全通道

七天入门Go语言 通道 & Goroutine | 第四天 并发编程

保持 wcf 回调通道无限期打开/如果出现故障则从客户端重新连接

强制 WCF 通道到 IP 地址