WCF客户端自动重新连接

时间:2014-12-25 09:41:57

标签: c# wcf

我有一个wcf服务,以及相应的客户端。当服务出现故障时,从客户端到服务的每次调用都会抛出异常。但我需要客户端重新连接,所以我将客户端包装到异常处理程序中并重新连接。 实现自动重新连接行为的首选方法是什么? 我的客户:

internal sealed class BloombergClient
{
    #region Singleton

    private static Lazy<BloombergClient> instance = new Lazy<BloombergClient>(() => new BloombergClient(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
    public static BloombergClient Instance { get { return instance.Value; } }

    #endregion

    private readonly ExceptionReconnectHandler exceptionHandler;
    private readonly Object lockObject = new Object();
    private readonly ManualResetEventSlim eventSlim = new ManualResetEventSlim(true);

    private BloombergModuleServiceClient client;
    private volatile Boolean isConnecting;

    public event System.EventHandler ConnectionEstablished;

    private BloombergClient()
    {
        this.exceptionHandler = new ExceptionReconnectHandler(HandleException);
        Connect();
    }

    //Example method
    public Double GetDailyClose(String bloombergTicker, DateTime date)
    {
        eventSlim.Wait();
        return exceptionHandler.Execute(() => this.client.GetDailyClose(bloombergTicker, date));
    }

    private void HandleException(Exception e)
    {
        Connect();
    }

    private void BloombergServiceClientFaulted(object sender, EventArgs e)
    {
        Connect();
    }

    private Boolean CreateClient()
    {
        Boolean init = false;
        if (this.client != null)
        {
            ((ICommunicationObject)client).Faulted -= BloombergServiceClientFaulted;
            ((ICommunicationObject)client).Closed -= BloombergServiceClientFaulted;
        }
        this.client = new BloombergModuleServiceClient();

        if (this.client.State == CommunicationState.Created)
        {
            ((ICommunicationObject)client).Faulted += BloombergServiceClientFaulted;
            ((ICommunicationObject)client).Closed += BloombergServiceClientFaulted;

            init = true;
        }
        else
        {
            init = false;
        }

        return init;
    }

    private void Connect()
    {
        lock (this.lockObject)
        {
            if (isConnecting) return;
            lock (this.lockObject)
            {
                if (isConnecting) return;
                isConnecting = true;
            }
        }

        //if (eventSlim.IsSet) return; - offcourse not working
        eventSlim.Reset();

        try
        {
            while (true)
            {
                try
                {
                    if (client != null && client.State == CommunicationState.Opened)
                    {
                        ((ICommunicationObject)client).Abort();
                    }

                    if (CreateClient())
                    {
                        break;
                    }
                }
                catch (Exception e)
                {
                    Log.Instance.WriteLineT(e.Message, "Bloomberg Client");
                }

                Thread.Sleep(1000);
            }
        }
        finally
        {
            eventSlim.Set();
            isConnecting = false;
            ConnectionEstablished.Raise(this);
        }

    }
}


public class ExceptionReconnectHandler
{
    private readonly Action<Exception> handler;

    public ExceptionReconnectHandler(Action<Exception> handler)
    {
        if (handler == null) throw new ArgumentNullException("handler");
        this.handler = handler;
    }

    public virtual T Execute<T>(Func<T> func)
    {
        if (func == null) throw new ArgumentNullException("func");

        while (true)
        {
            try
            {
                return func();
            }
            catch (Exception e)
            {
                handler(e);
            }
        }
    }

    public virtual void Execute(Action action)
    {
        if (action == null) throw new ArgumentNullException("action");

        while (true)
        {
            try
            {
                action();
                return;
            }
            catch (Exception e)
            {
                handler(e);
            }
        }
    }
}

0 个答案:

没有答案