views:

79

answers:

4

I've create a Windows Service using C# that when OnStart is called creates a new thread from another class. This new thread then loops waiting for any incoming TCP connections. Or it should. When I start the service it automatically stops after about 5 seconds. I don't know why it is doing this. I understand that services close on their own if they have no work to do but the work has been specified for it. Anyone got any ideas why this would be happening? My OnStart Method looks like this:

protected override void OnStart(string[] args)
    {
        Thread thread = new Thread(new StateMachine().AcceptConnections);
        thread.Start();      
    }

Which then calls this method:

        Int32 port = 13000;
        IPAddress localAddr = IPAddress.Parse("127.0.0.1");

        server = new TcpListener(localAddr, port);

        // Start listening for client requests.
        server.Start();
        // Enter the listening loop.
        do
        {
            client = server.AcceptTcpClient();
            ReceivedData();                
        } while (true);
    }

It does not stay on long enough to allow any clients to connect to the TcpListner.

Help?

+1  A: 

First, make sure you app code runs OK when not set up as a service. If your code runs OK when not set up as a service, my guess is that your OnStart is taking too long for some reason. If you cannot speed it up, the info here allows you to handle necessary startup latency.

In Win32, you have to update the service status by notifying the Service Control Manager (SCM) of startup (and stop) progress periodically, or it will think your service is hung and kill it. You may need to do this only once, or on a timer if your initialization takes a long time. While your startup (stop) logic is in progress, you tell SCM you are in state START_PENDING (STOP_PENDING) and once it's done you tell it you are in STARTED (STOPPED) state.

In the managed world, this goal is achieved by calling ServiceBase.RequestAdditionalTime. There is a thorough overview of this topic here. The money quote:

This is where your managed service needs to pay attention to avoid the SCM flagging your service as unresponsive.

  • You don’t have to explicitly update the state; ServiceBase does this for you when your OnStart or OnStop method completes
  • You do have to call RequestAdditionalTime if you expect the OnX method to exceed the timeout.
Steve Townsend
The app is working fine when it is a standalone console app, both the client and the server can connect and interact. I added in a try catch on the acceptconnections method and it must be catching an exception because the service doesnt stop anymore but I still can't connect to the server with the client. I assume this is because it caught the exception and hasn't actually created the server so therefore the client has nothing to connect to.
stuartmclark
I am wanting to the acceptconnections method to run forever to recieve any new incoming connections through Tcp. I'm beginning to think that this might not be possible as the SCM will think, as you said, that my app has died and will kill it. Is there a way for me to do this?
stuartmclark
@stuartmclark - follow earlier suggestions and get the exception output to a log file or the Event Viewer. Having your code run forever is fine (that's what services as are supposed to do) so long as SCM interaction time in `OnStart` and siblings is managed per my response. Does not sound like that is your issue at this point though - just a socket failure? Diags will show you for sure, and you will need this to support your code anyway.
Steve Townsend
A: 

I agree with SWeko, insert Thread.Sleep(10000) at the first line of ur OnStart method and debug it.

SaeedAlg
+1  A: 

Firstly, are you sure you want your service to spawn a new thread to do this? You can't simply do it on the main thread?

To debug your problem, do one or both of the following:

  1. Add some logging, either using the EventLog or a logging framework (Log4Net).
  2. Run your service as a console app and debug it in Visual Studio
Jaco Pretorius
I ran it as a console app and it stops when I create the server i.e. server = new TcpListener(localAddr,port).How do I create or add to the EventLogs, it is already set to autolog = false, but whenever I try to call EventLog.WriteEntry it says that the service started and then stopped suddenly. I'm stuck.
stuartmclark
So did you put a breakpoint on that line? What happens when you step into the code? Try and put a try-catch block around the code that you think is causing the issue to try and see if any exceptions occur. Check this MSDN article to see how to write to the eventlog - it's very easy. http://support.microsoft.com/kb/307024
Jaco Pretorius
Hmm, I have got it down to a configuration error. I removeed the app.config file I have created and it seems to be working for now. I think I have either referenced or created the app.config file incorrectly. Thanks for all your help though!
stuartmclark
Please mark the answer as correct if you found it useful
Jaco Pretorius
A: 

Right I've got it. I was doing something stupid with the config file, which including moving the .exeXML config file to the wrong place. Which resulted in an Configuration Error, and the service wasn't liking it. I've got it up and running now though. So thanks for your help.

stuartmclark