none
ServiceHost.Open() closing straight away. RRS feed

  • Question

  • Hi Folks,

      I have a console app that has a WCF (basic HTTP Binding) listening for HTTP request and a TCP Socket listener waiting for TCP socket connections.

      The application structure looks something like this (what I currently have):-

    // What I currently have
    public static void main() 
    {
        Foo fooHttp = new Foo();
        Bar barTCP = new Bar();
    
        fooHttp -> start();
        barTCP -> start();
    }
    
    // What I would like to do
    public static void main()
    {
        Foo fooHttp = new Foo();
        Bar barTCP = new Bar();
    
        Task.Factory.StartNew( () => { fooHttp -> start(); }, TaskCreationOptions.LongRunning() );
    
        Task.Factory.StartNew( () => { barTCP -> start(); }, TaskCreationOptions.LongRunning() };
    
        // Wait for both threads to complete before cleaning
        // up and exiting.  Threads are signalled to close
        // by setting some kind of semaphore in each one.
    }
    

    The issue that I am having, is that while the TCP listener has a while() loop that sits and waits for incomming connections and so blocks its thread, the HTTP listener has no such mechanism, what is happening, is that in the start() method, I call serviceHost.Open(), the method completes and the serviceHost is closed (no longer responds to calls). 

    If I put a Console.ReadLine() immediately after the open() call for testing and block the thread, it remains open and works. Since I cant use a readline call, what do I replace it with?

    So My question is, how can I get this thread to sit and wait for requests rather than going out of scope?

    I thought about adding a while() loop that checks for CancellationToken, but I am not sure how to pause the loop without creating either a spin loop, or sleeping (and delaying incoming calls).

    anyone have any thoughts?

    Regards

    Monday, May 28, 2018 11:58 PM

All replies

  • Hi AndyW2007,

    Could you share us a simple demo which could reproduce your issue?

    I made a test with code below to start and stop WCF Service.

        public class WCFSvc
        {
            public ServiceHost host = new ServiceHost(typeof(Service1));
    
            public void Start()
            {
                host.Open();
                Console.WriteLine("Service starts");
            }
            public void Stop()
            {
                host.Close();
                Console.WriteLine("Service closes");
            }
        }
    ----
            static void Main(string[] args)
            {
                WCFSvc wcf = new WCFSvc();
                Task.Factory.StartNew(() => {
                    wcf.Start();
                });
                Console.ReadLine();
                Task.Factory.StartNew(() => {
                    wcf.Stop();
                });
                Console.ReadLine();
            }
    

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, May 29, 2018 2:21 AM
  • Hi,

      Remove your first readline().

      For my workaround,

    // Declare a CancelationTokenSource
    
    TaskFactory taskFactory = new TaskFactory(cancelSource.Token);
    List<Task> taskList = new List<Task>();
    
    // Add the tasks to the tasklist
    taskList.Add( taskfactory.StartNew(... //HTTP
    taskList.Add( taskFactory.StartNew(... //TCP
    
    
    // Do some busy stuff here, in this example just wait until
    // user wants to quit
    Console.ReadLine();
    
    // Signal cancel, then wait for them to gracefully close.
    cancelSource.Cancel();
    Task.WaitAll(taskList.ToArray();
    
    
    

    In the HTTP thread I added a while() on communicationState.opening|opened, then just checked the cancelSource.IsCancellationRequested and break the loop when it is set.  I added a Sleep(5s) to the loop.

    The TCP socket, does something similar.

    This works, but my concern is still with the injected Sleep.  It looks like when a request arrives a new thread is created to handle the request so the sleep has no effect. But this needs to be tested.


    Tuesday, May 29, 2018 3:17 AM
  • Hi Andy,

    Is there any reason you want to start and stop the service directly?

    If the first "Console.ReadLine" is removed, the service will stop directly.

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, May 29, 2018 5:48 AM
  • Hi,

    I just looked back at your example again.

    There are two service hosts running concurrently, the first is HTTP and the second is TCP,  The issue was that the first was exiting before the second one ran as it does not block when waiting for requests in the same way as the TCP one does, I needed a way to get them to run together.

    Tuesday, May 29, 2018 9:28 PM
  • What do you mean by "two service hosts"? I only define one service by

    public ServiceHost host = new ServiceHost(typeof(Service1));

    And then access the host in two threads.

    If you did not exist the Console app and nor call "wcf.Stop()", WCF will keep running all the time.

    Maybe code below would be understand easiler.

    public class WCFSvc
        {
            public ServiceHost host = new ServiceHost(typeof(Service1));
    
            public void Start()
            {
                host.Open();
                Console.WriteLine("Service starts");
            }
            public void Stop()
            {
                host.Close();
                Console.WriteLine("Service closes");
            }
        }
    ----
            static void Main(string[] args)
            {
                WCFSvc wcf = new WCFSvc();
                Task.Factory.StartNew(() => {
                    wcf.Start();
                });
                Console.ReadLine();
            }

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, May 30, 2018 2:08 AM