为整个应用程序保留一个wcf客户端代理

时间:2012-02-20 03:20:43

标签: c# .net asp.net-mvc wcf wcf-client

我有高负载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();
        }
    }

那么,你们怎么想呢?它应该运作正常吗?有时我的应用程序被卡住了我认为这是因为客户端代理状态确定不正确,而app尝试使用损坏的代理。


POST EDIT

同样在TCP Monitor中,我看到了从站点到服务的许多已建立的连接。为什么它会创建大量的连接而不是使用一个全局?可能在调用服务方法时发生了一些异常使其出现故障状态?

希望你的帮助!

1 个答案:

答案 0 :(得分: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);            
        }
}