Where to trap failed connection on WCF calling class?

后端 未结 7 1147
失恋的感觉
失恋的感觉 2021-01-13 05:09

I\'m trying to write a class that encapsulates WCF calls (the client is Silverlight, if it matters). It all works swimmingly, but I\'m not sure how to trap a connection fail

7条回答
  •  执念已碎
    2021-01-13 05:34

    I've encountered a similar problem before. The main problem is with the way IDisposable is implemented on instances of your proxy/channel. The way I've solved it is shown in the code below, where IDirector is my service contract:

    public class ProxyWrapper : IDisposable
    {
        private IDirector proxy;
        private ChannelFactory factory;
        int callCount = 0;
    
        public ProxyWrapper()
        {
            factory = new ChannelFactory();
    
            proxy = factory.CreateChannel();
        }
    
        public IDirector Proxy
        {
            get
            {
                if (callCount > 0)
                    throw new InvalidOperationException("The proxy can only be accessed once for every ProxyWrapper instance. You must create a new ProxyWrapper instance for each service request.");
                // only allow the proxy/channel to be used for one call.
    
                callCount++;
                return proxy;
            }
        }
    
        public void Dispose()
        {
            IClientChannel channel = (IClientChannel)proxy;
    
            try
            {
                if (channel.State != CommunicationState.Faulted)
                {
                    channel.Close();
                }
                else
                {
                    channel.Abort();
                }
            }
            catch (CommunicationException)
            {
                channel.Abort();
            }
            catch (TimeoutException)
            {
                channel.Abort();
            }
            catch (Exception)
            {
                channel.Abort();
                throw;
            }
            finally
            {
                channel = null;
                proxy = null;
            }
        }
    }
    

    The way to use the above class is as follows:

        public static void Login(string userName, string password)
        {
            using (ProxyWrapper wrapper = new ProxyWrapper())
            {
                currentSession = wrapper.Proxy.Login(userName, password);
            }
        }
    

    Because the ProxyWrapper class implements IDisposable, if we use an instance of the ProxyWrapper class inside a using block, the Dispose() method is guaranteed to be called, even if an exception is thrown. The code in the Dispose() method will handle all cases and states of the proxy/channel. You can then add your error-handling / logging / event delegate code in this method.

    Read the following blog entry for more info, and for a more generic version of the code above: http://bloggingabout.net/blogs/erwyn/archive/2006/12/09/WCF-Service-Proxy-Helper.aspx

提交回复
热议问题