WCF: Retry when service is in fault state.

Service Host:

using System;

using System.Configuration;

using System.ServiceModel;

using System.ServiceModel.Activation;

using System.Web.Configuration;

using log4net;

using System.Threading;



namespace Test.Custom

{

    public class CustomServiceHostFactory : System.ServiceModel.Activation.WebServiceHostFactory

    {

        private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)

        {

            log4net.Config.XmlConfigurator.Configure();



            CustomServiceHost customServiceHost = new CustomServiceHost (serviceType, baseAddresses);

            log.Info("Create Service Host called");



            customServiceHost.incomingServiceType = serviceType;

            customServiceHost.incomingBaseAddresses = baseAddresses;

            customServiceHost.Faulted += customServiceHost.OnServiceHostFaulted;



            return customServiceHost;

        }

    }



    public class CustomServiceHost : ServiceHost

    {

        public Type incomingServiceType { get; set; }

        public Uri[] incomingBaseAddresses { get; set; }



        private int Attempts = 0;

        private bool isSuccess = false;



        private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public CustomServiceHost (Type serviceType, params Uri[] baseAddresses)

            : base(serviceType, baseAddresses)

        {

            log.Info("CustomServiceHost constructor called");

        }



        protected override void ApplyConfiguration()

        {

            base.ApplyConfiguration();

        }



        public void OnServiceHostFaulted(object sender, EventArgs e)

        {

            log.Info("Host state is fault.");

            ICommunicationObject faultedHost = (ICommunicationObject)sender;

            faultedHost.Abort();



            faultedHost = new ServiceHost(this.incomingServiceType, this.incomingBaseAddresses);

            //faultedHost.Faulted += this.OnServiceHostFaulted;



            log.Info("Host state is " + faultedHost.State.ToString());



            if (Attempts < 5 && isSuccess == false)

            {

                Attempts++;

                log.Info("Retry to create server host for the" + Attempts + "time");

                try

                {

                    if (isSuccess == false)

                    {

                        Thread.Sleep(1 * 1000);

                    }

                    faultedHost.Open();

                    isSuccess = true;

                }

                catch (Exception ex)

                {

                    faultedHost.Abort();

                    log.Info("Host state is " + faultedHost.State.ToString());

                    log.Info("Exception:  " + ex.Message);

                }

            }

        }



        //protected override void OnFaulted()

        //{

        //    base.OnFaulted();

        //}



    }

}
CustomServiceHostFactory.cs

1. 创建一个自定义的HostFactory,继承自WebServiceHostFactory;

2. 重载CreateServiceHost方法,并在方法内添加ServiceHost对象的Faulted的EventHandler处理;

3. 对自定义Faulted EventHandler方法根据需要加入Retry。

 

Service Client:

using Microsoft.ServiceBus;

using System;

using System.Collections.Generic;

using System.Linq;

using System.ServiceModel;

using System.Text;

using System.Threading.Tasks;



namespace Test.WCF.ServiceBus.Client

{

    class Program

    {

        public static ChannelFactory<IMediaServicesManagementServiceChannel> testCF=null;

        static void Main(string[] args)

        {



            Retry(

                () =>

                {

                    bool flag = false;

                    var cf = new ChannelFactory<IMediaServicesManagementServiceChannel>(

                                   new NetTcpRelayBinding(),

                                   new EndpointAddress(ServiceBusEnvironment.CreateServiceUri("sb", "***Service Bus Name***", "***Relay Name***")));



                    cf.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior { TokenProvider = TokenProvider.CreateSharedSecretTokenProvider("owner", "***Service Bus Token***") });



         

                    var ch1 = cf.CreateChannel();



                    try

                    {

                        Console.WriteLine(ch1.AddNumbers(3, 4));

                        flag = true;

                    }

                    catch

                    {

                        ch1.Abort();

                        flag = false;

                    }

                    finally

                    {

                        if (ch1 != null)

                        {

                            ch1.Close();

                        }

                    }

                    return flag;

                },

                5);

            





            Console.WriteLine("Press ENTER to close");

            Console.ReadLine();

        }



        public static void Retry(Func<bool> task, int times)

        {

            bool flag = false;

            

            for (int i = 0; i < times; i++ )

            {

                flag = task();

                

                if(flag==true)

                {

                    break;

                }

            }

        }





    }

}
Program.cs

 

Referece Links:

http://msdn.microsoft.com/en-us/library/windowsazure/hh966775.aspx

 

你可能感兴趣的:(service)