none
How to restart a WCF Pooling Duplex Service in Windows Service RRS feed

  • Question

  • I am using an windows service to host the WCF Pooling Duplex Service, whenever wcf service enters the faulted state I want to restart the WCF Duplex Service. - Restart of normal WCF Service works fine but when I try to restart the WCF Duplex Service it throws an following exception.
     

    The ChannelDispatcher at 'http://localhost:8731/TestService' with contract(s) 
    "ITestService"' is unable to open its IChannelListener.


    This is the inner exception and its stack trace
     
    Innerexception

    A registration already exists for URI http://localhost:8731/TestService'.


    StackTrace

       at System.ServiceModel.Channels.UriPrefixTable 1.RegisterUri(Uri uri, HostNameComparisonMode hostNameComparisonMode, TItem item)
       at System.ServiceModel.Channels.HttpTransportManager.Register(TransportChannelListener channelListener)
       at System.ServiceModel.Channels.TransportManager.Open(TransportChannelListener channelListener)
       at System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTransportManagersCallback selectTransportManagerCallback)
       at System.ServiceModel.Channels.TransportChannelListener.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.HttpChannelListener`1.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.PollingDuplexChannelListener.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)

    I tried to create a small sample code which is as follows.
     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.ServiceModel;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace WindowsHostedWcfService
    {
        public partial class Service1 : ServiceBase
        {
            public Service1()
            {
                InitializeComponent();
            }
     
            protected override void OnStart(string[] args)
            {
     
                try
                {
                    // Creating the Service Host object for service "TestService"
                    ServiceHost TestService = new ServiceHost(typeof(TestService));
                    // Openiong the Service
                    TestService.Open();
                    TestService.Faulted += TestService_Faulted;
     
                    // Closing the service and wait for the service to close
                    AsyncCallback AsyncCallback = new System.AsyncCallback(CloseCompleted);
                    TestService.BeginClose(AsyncCallback, null);
                }
                catch (Exception Ex)
                {
     
                }
            }
     
            private void CloseCompleted(IAsyncResult i)
            {
                // Creating the new service host object .
                TestService ts = new TestService();
                ServiceHost TestService1 = new ServiceHost(ts);
     
                // When try to reoprn the service it throws the exception here ,
                TestService1.Open();
                TestService1.Faulted += TestService_Faulted;
            }
     
            void TestService_Faulted(object sender, EventArgs e)
            {
     
            }
     
            protected override void OnStop()
            {
     
            }
     
            public void Run()
            {
                OnStart(new string[] { });
            }
        }
     
    
        // Service implementing the Duplex Contract 
        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
        public class TestService : ITestService
        {
            public TestService()
            {
     
            }
     
            public void TestMethod()
            {
                throw new Exception();
            }
        }
     
    
        // A Simple duplex WCf Service with the call back contract of type ICallBack
        [ServiceContract(CallbackContract = typeof(ICallBack))]
        public interface ITestService
        {
            [OperationContract]
            void TestMethod();
        }
     
        // Callback COntract
        [ServiceContract]
        public interface ICallBack
        {
            // Operatin contract with oneway property set to True
            [OperationContract(IsOneWay = true)]
            void TestCallbackMethod();
        }
    }


    So because of this every time the WCf service goes into the faulted state I have to restart my windows service so that WCF service starts running,

     
    thanks!





    • Edited by Nirav Savla Thursday, November 6, 2014 1:23 PM
    Thursday, November 6, 2014 1:19 PM

All replies

  • Hello, I had made the following test and it works for me:

       // Creating the Service Host object for service "TestService"
                    ServiceHost TestService = new ServiceHost(typeof(TestService));
    
    
                    WSDualHttpBinding binding = new WSDualHttpBinding();
                    EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
                    binding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");
    
                    TestService.AddServiceEndpoint(typeof(ITestService), binding,
                        new Uri("http://localhost:8731/TestService"));
                    // Openiong the Service
                    TestService.Open();
                    TestService.Faulted += TestService_Faulted;
    
                    // Closing the service and wait for the service to close
                    AsyncCallback AsyncCallback = new System.AsyncCallback(CloseCompleted);
                    TestService.BeginClose(AsyncCallback, null);

    Thursday, November 6, 2014 5:02 PM
  • Hi Deric,

    Thanks for the reply, 

    We are not facing any issue in closing the service, but after closing the service when I tries to open it again then it gives me the exception.


    Friday, November 7, 2014 5:21 AM
  • Hi,

    About this situation, Windows Services are controlled using the Services applet in Control Panel and can be configured to start up automatically after a system reboot.

    Besides, you could also refer to the following links for more information:

    http://msdn.microsoft.com/en-us/library/vstudio/ms751414(v=vs.100).aspx

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/5de9196e-f75f-464a-be89-7e303ba60991/servicehosts-conflict-on-address-when-unit-tested?forum=wcf

    Regards

    Friday, November 7, 2014 9:14 AM
    Moderator
  • Call ServiceHost.Abort() after close.

    http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.communicationobject.abort(v=vs.110).aspx

    Friday, November 7, 2014 9:29 AM
  • hi, 

    Thnx for the reply ,

         
            ServiceHost TestService;
            protected override void OnStart(string[] args)
            {
    
                try
                {
                    // Creating the Service Host object for service "TestService"
                    TestService = new ServiceHost(typeof(TestService));
                    // Openiong the Service
                    TestService.Open();
                    TestService.Faulted += TestService_Faulted;
    
                    // Closing the service and wait for the service to close
                    AsyncCallback AsyncCallback = new System.AsyncCallback(CloseCompleted);
                    TestService.BeginClose(AsyncCallback, null);
                }
                catch (Exception Ex)
                {
    
                }
            }
    
            private void CloseCompleted(IAsyncResult i)
            {
                TestService.Abort();
                try
                {
                    // Creating the new service host object .
                    TestService ts = new TestService();
                    ServiceHost TestService1 = new ServiceHost(ts);
    
                    // When try to reoprn the service it throws the exception here ,
                    TestService1.Open();
                    TestService1.Faulted += TestService_Faulted;
                }
                catch (Exception Ex)
                {
                    
                }
            }

    I am still getting the exception , I dont know ehere I am wrong.

    This is what I have configured in my App.config file

         <services>
            <service  name="WindowsHostedWcfService.TestService" behaviorConfiguration="MCollector.MLiveWCFService.DataServiceBehavior">
            <endpoint address="" binding="pollingDuplexHttpBinding" contract="WindowsHostedWcfService.ITestService" bindingConfiguration="multipleMessagesPerPollPollingDuplexHttpBinding"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
            <endpoint address="wsDualHttpBinding"  binding="wsDualHttpBinding" contract="WindowsHostedWcfService.ITestService" bindingName="wsDualHttpBinding">
            </endpoint>
            <endpoint address=""  binding="netTcpBinding" bindingConfiguration="netTcpBinding" contract="WindowsHostedWcfService.ITestService">
            </endpoint>        
            <!--<endpoint binding="customBinding" contract="MCollector.MLiveWCFService.IDataService" bindingName="mCollectorCustomBinding" bindingConfiguration="CustomBindingConfiguration"></endpoint>-->
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8731/TestService" />
                <add baseAddress="net.tcp://localhost:5511/TestService" />
              </baseAddresses>
            </host>
          </service>


    Friday, November 7, 2014 11:14 AM
  • Hey, I have tested it and worked:

            private static void TestServiceRestart()
            {
                try
                {
                    // Creating the Service Host object for service "TestService"
                    ServiceHost TestService = new ServiceHost(typeof(TestService));
    
    
                    WSDualHttpBinding binding = new WSDualHttpBinding();
                    EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
                    binding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");
    
                    TestService.AddServiceEndpoint(typeof(ITestService), binding,
                        new Uri("http://localhost:8731/TestService"));
                    // Openiong the Service
                    TestService.Open();
                    TestService.Faulted += TestService_Faulted;
    
                    // Closing the service and wait for the service to close
                    AsyncCallback AsyncCallback = CloseCompleted;
                    TestService.BeginClose(AsyncCallback, null);
    
                    TestService.Abort();
                }
                catch (Exception Ex)
                {
    
                }
            }
    
            private static void CloseCompleted(IAsyncResult i)
            {
                // Creating the Service Host object for service "TestService"
                ServiceHost TestService = new ServiceHost(typeof(TestService));
    
    
                WSDualHttpBinding binding = new WSDualHttpBinding();
                EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
                binding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");
    
                TestService.AddServiceEndpoint(typeof(ITestService), binding,
                    new Uri("http://localhost:8731/TestService"));
                // Openiong the Service
                TestService.Open();
                TestService.Faulted += TestService_Faulted;
            }
    
            private static void TestService_Faulted(object sender, EventArgs e)
            {
    
            }

    Just Call the method bellow and put the breakpoints.

    TestServiceRestart
    Friday, November 7, 2014 11:36 AM
  • Hi,

    Thanks for the reply,

    Your solution works !

    But when I tries to load the binding and endpoint config from the App.config file then it throws the same exception.

    Can you just help me with the configuring it in the App.config file

    Thanks again.....

    Friday, November 7, 2014 12:31 PM
  • What a good new!

    Please post the full config, because I need:

    1. behaviorConfiguration="MCollector.MLiveWCFService.DataServiceBehavior"
    2. binding="pollingDuplexHttpBinding" 
    3. bindingConfiguration="multipleMessagesPerPollPollingDuplexHttpBinding"
    4. bindingConfiguration="netTcpBinding"
    Friday, November 7, 2014 12:53 PM
  • hii,

      Sorry for the late reply,

    Actually the code which you have provided have an WsDualHttpBinding and I want to do the same with the PollingDuplexHttpBinding , so when I try it with PollingDuplexHttpBinding in your code it gives me an error.

    Here is my Config file for the same

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
        <system.serviceModel>
            <extensions>
          <bindingExtensions>
            <add name="pollingDuplexHttpBinding" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement,System.ServiceModel.PollingDuplex, Version=4.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
          </bindingExtensions>
        </extensions>
            <bindings>
          <customBinding>
            <binding name="CustomBindingConfiguration">
              <binaryMessageEncoding />
                 <tcpTransport maxBufferPoolSize="524288" maxReceivedMessageSize="65536" hostNameComparisonMode="StrongWildcard"
                               maxBufferSize="65536" maxPendingConnections="10" channelInitializationTimeout="00:01:00"
                               transferMode="Buffered" listenBacklog="10" portSharingEnabled="false" teredoEnabled="false">
              </tcpTransport>
            </binding>
          </customBinding>
          <wsDualHttpBinding>
            <binding name="wsDualHttpBinding" receiveTimeout="02:00:00" sendTimeout="00:00:02"
              maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483646"
                maxArrayLength="2147483646" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <security mode="Message">
                <message clientCredentialType="UserName" />
              </security>
            </binding>
          </wsDualHttpBinding>
          <netTcpBinding>
            <binding name="netTcpBinding" receiveTimeout="15:00:00" sendTimeout="00:00:05"
              maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
              <security mode="None">
              </security>
            </binding>
          </netTcpBinding>
          
          <pollingDuplexHttpBinding>
            <binding name="multipleMessagesPerPollPollingDuplexHttpBinding" sendTimeout="00:00:05" receiveTimeout="24:00:00:00"
                     inactivityTimeout="24:00:00:00" openTimeout="00:00:10"
                     duplexMode="MultipleMessagesPerPoll" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483646"
                maxArrayLength="2147483646" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            </binding>
          </pollingDuplexHttpBinding>
          
        </bindings>
         <services>
            <service  name="WindowsHostedWcfService.TestService" behaviorConfiguration="MCollector.MLiveWCFService.DataServiceBehavior">
            <endpoint address="" binding="pollingDuplexHttpBinding" contract="WindowsHostedWcfService.ITestService" bindingConfiguration="multipleMessagesPerPollPollingDuplexHttpBinding"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
            <endpoint address="wsDualHttpBinding"  binding="wsDualHttpBinding" contract="WindowsHostedWcfService.ITestService" bindingName="wsDualHttpBinding">
            </endpoint>
            <endpoint address=""  binding="netTcpBinding" bindingConfiguration="netTcpBinding" contract="WindowsHostedWcfService.ITestService">
            </endpoint>        
            <!--<endpoint binding="customBinding" contract="MCollector.MLiveWCFService.IDataService" bindingName="mCollectorCustomBinding" bindingConfiguration="CustomBindingConfiguration"></endpoint>-->
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8731/TestService" />
                <add baseAddress="net.tcp://localhost:5511/TestService" />
              </baseAddresses>
            </host>
          </service>
                 </services>
    
          <behaviors>
          <serviceBehaviors>
            <behavior name="MCollector.MLiveWCFService.DataServiceBehavior">
              <serviceMetadata httpGetEnabled="false" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"></dataContractSerializer>
            </behavior>
          </serviceBehaviors>
        </behaviors>
                    </system.serviceModel>
    </configuration>
    

    Thanks...

    Tuesday, November 11, 2014 9:37 AM
  • Hello,

    I was able to reproduce your problem using your config.

    I have tried this sample and it works too: http://cid-7cedcb8ed3a44629.skydrive.live.com/self.aspx/Public/WcfSampleServiceHost.zip from http://blogs.msdn.com/b/johnwpowell/archive/2008/09/20/how-to-create-a-reusable-wcf-service-host-for-windows-services-and-self-hosting.aspx

    I'm thinking there is an issue with you Silverlight binding :(



    What's the framework version you're using?
    Tuesday, November 11, 2014 12:31 PM
  • Hi,

    I download your sample but it contains the WsHttpBinding, I am facing that problem because of PollingDuplexBinding. 

    I am using framework 4.5 For .net and Silverlight 5.

    thanks.

    Wednesday, November 12, 2014 10:19 AM
  • I got it. I reproduced your problem using the SilverLight binding. I did not find a way to it helps! :(
    I suggested the example because it deals with ServiceHost in a diferente way that could be helpful and solves your problem. But obviously you should change the binding from example to your type.

    Wednesday, November 12, 2014 4:03 PM
  • Hi ,

    Thanks for the help, 

    The issue with the Silverlight is it only support the PollingDuplex Binding for the duplex communication. So I cant change it to any other binding and as it gives me the error on restart I have to always restart my windows service. But after restarting the windows service it works fine for me.

    Thanks again.

    Thursday, November 13, 2014 5:56 AM