为整个应用程序保留一个 wcf 客户端代理
Posted
技术标签:
【中文标题】为整个应用程序保留一个 wcf 客户端代理【英文标题】:Keeping one wcf client proxy for whole app 【发布时间】:2012-03-10 11:28:47 【问题描述】:我有高负载的 ASP .NET MVC2 网站和该网站使用的 WCF 服务。早期我每次需要它时都创建一个代理,甚至没有关闭它。参考我的previous question(非常感谢SO用户Richard Blewett)我发现我应该关闭这个代理。以其他方式它将成功会话限制。
现在,我在应用启动时创建代理,然后只需检查它并在需要时重新创建它。所以,这里是代码:
public static bool IsProxyValid(MyServ.MyService client)
bool result = true;
if ((client == null) || (client.State != System.ServiceModel.CommunicationState.Opened) // || (client.InnerChannel.State != CommunicationState.Opened)
)
result = false;
return result;
public static AServ.AServClient GetClient(HttpContext http)
if (!IsProxyValid((MyService)http.Application["client"]))
http.Application["client"] = new MyService();
return (MyService)http.Application["client"];
public static MyServ.MyService GetClient(HttpContextBase http)
if (!IsProxyValid((MyService)http.Application["client"]))
http.Application["client"] = new MyService();
return (MyService)http.Application["client"];
public ActionResult SelectDepartment(string departments)
try
MyService svc = CommonController.GetClient(this.HttpContext);
Department[] depsArray = svc.GetData(departments);
// .... I cut here ....
return View();
catch (Exception exc)
// log here
return ActionUnavailable();
那么,你们怎么看呢?它应该正常工作吗?有时我的应用程序卡住了。我认为这是因为客户端代理状态确定不正确,并且应用程序尝试使用损坏的代理。
后编辑
在 TCP Monitor 中,我还看到了很多从站点到服务的已建立连接。为什么它会创建很多连接而不是使用一个全局连接?可能是在调用服务方法时发生了一些异常使其处于故障状态?
希望大家帮忙!
【问题讨论】:
【参考方案1】:我认为如果在创建新通道之前出现故障,您需要中止通道,并且 如果您创建新客户端,请确保关闭/中止旧客户端,为此使用类似的东西(这个在单例中与 DI 一起使用)
public class MyServiceClientInitializer : IMyServiceClientInitializer
[ThreadStatic]
private static MyServ.MyService _client;
public MyServ.MyService Client
get
if (_client == null
|| (_client.State != CommunicationState.Opened
&& _client.State != CommunicationState.Opening))
IntializeClient();
return _client;
private void IntializeClient()
if (_client != null)
if (_client.State == CommunicationState.Faulted)
_client.Abort();
else
_client.Close();
string url = //get url;
var binding = new WSHttpBinding();
var address = new EndpointAddress(url);
_client = new MyServ.MyService(binding, address);
【讨论】:
好的,谢谢您的回答!我应该检查client.InnerChannel.State
和client.State
还是只检查client.State
?
我尝试了您的解决方案,但是有很多连接,而不仅仅是一个。我做错了什么?
MyServiceClientInitializer 应该是单例
我通过 Visual Studio 进行调试,然后查看只创建了一次的连接。但为什么它会建立如此多的物理连接呢?
IntializeClient 方法是否只被调用一次?以上是关于为整个应用程序保留一个 wcf 客户端代理的主要内容,如果未能解决你的问题,请参考以下文章
终于解决:升级至.NET 4.6.1后VS2015生成WCF客户端代理类的问题