重用 WCF 服务客户端

Posted

技术标签:

【中文标题】重用 WCF 服务客户端【英文标题】:Reuse of WCF service clients 【发布时间】:2011-06-06 10:25:33 【问题描述】:

我有一个 WCF Web 服务,它充当我的 ASP.NET 网页的数据提供者。

在整个网页中,通过自动生成的 ServiceClient 对 Web 服务进行了多次调用。

目前我创建一个新的 ServiceClient 并为每个请求打开它,即获取用户、获取角色、获取客户列表等......其中的每一个都会创建一个新的 ServiceClient 并打开一个新的连接。

我能否使我的 ServiceClient 类成为全局或静态可用的类,以便我的 ASP.NET 网页中的所有功能都可以使用同一个客户端。这似乎更有效率。这样做有什么问题吗?这样做时我应该考虑什么建议?

如果我向客户端发出多个请求会怎样?大概它都是同步的,所以我对它进行 1 次或 50 次调用都没有关系?

谢谢

【问题讨论】:

【参考方案1】:

当使用面向会话(具有安全上下文或可靠会话的 wsHttp)或连接(net.tcp、net.pipe)的绑定时,您必须以您希望处理会话的方式处理您的代理。因此,如果您共享代理,所有调用都将在单个 WCF 会话中处理(默认情况下由单个服务实例处理)。但是您必须处理额外的复杂性,例如:未处理的服务异常将终止您的频道,并且来自客户端的以下调用将导致异常。

当使用无会话 HTTP 绑定(basicHttp、webHttp)时,您可以共享您的代理,甚至可以将其设为静态。每个调用都是单独处理的,服务上的异常不会导致通道出错,它是透明的reuses opened HTTP persistent connections。但是正因为如此,创建新的代理/通道应该没有太大的开销。

所以我的建议是:当您在 ASP.NET 应用程序的单个请求处理中需要多次调用您的服务时,请使用相同的代理/通道。但是不要在不同的请求之间共享代理/通道。

【讨论】:

这个答案还有效吗?这说明了别的东西:***.com/a/9636583/6841224 这似乎对 .NET Standard 版本的 WCF 有效,根据此评论:github.com/dotnet/wcf/issues/4153#issuecomment-585928337。【参考方案2】:

我认为使用ChannelFactory 可以解决您的问题。如果我是对的,ChannelFactory 拥有您的连接池并重新使用这些频道。这样做的好处是通道不会每次都被实例化,只有第一个。

在此处阅读更多信息:ChannelFactory

要处理通道的处置,您需要一些特殊处理,因为通道可以在处置中抛出异常。我写了一个映射器来处理这个问题,你可以在这里阅读:http://blog.tomasjansson.com/2010/12/disposible-wcf-client-wrapper/

【讨论】:

这难道不是简单地为每个请求创建一个新连接,而不是通过一个连接传递我的所有请求吗? 我不认为它为每个请求创建一个连接,它只是打开它(当你调用 open 时)......但我不是 100% 确定。我认为创建连接是花费很多的部分。这可以很容易地检查,实现一个像这样的简单客户端并在您定时调用的地方进行两次相同的调用。如果我是对的,第二次通话应该会快得多。 而通常你想永远保持连接打开,常规流程是打开连接,调用然后关闭。

以上是关于重用 WCF 服务客户端的主要内容,如果未能解决你的问题,请参考以下文章

WCF常见类型不重用

WCF ChannelFactory 和通道 - 缓存、重用、关闭和恢复

WCF 服务证书认证

WCF - 创建简单WCF客户端实现与WCF服务端通信

从客户端调用 WCF 服务

从非 Microsoft 客户端访问 WCF 服务回调