3

I am developing a windows service that is able to receive socket connection, so in the OnStart method:

protected override void OnStart(string[] args)
{
    start();
}

The start function looks like this:

public async void Start()
{
      //initialization things
      ...
      ...
      TcpListener listener = new TcpListener(IPAddress.Any, port);
      listener.Start();
      while(true)
      {
          TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
          ...
      }
      ...    
}

The problem is that no connection is accepted, while same code run perfect in standard command line project, I doubt there is a problem in my design, which thread runs the OnStart method?, when control goes back to OnStart after awaiting the accept process, is the async method ignored as it is a special case in windows service? Any suggestions is welcomed

5
  • Most likely an uncaught exception caused your service to fail, because any exceptions will not be caught. Look into Taskscheduler.UnobservedTaskException, check your event log and refresh your services screen. learn.microsoft.com/en-us/dotnet/api/… Commented Mar 5, 2019 at 9:03
  • After checking event log, no unobserved exception there :(
    – ammcom
    Commented Mar 5, 2019 at 9:10
  • Change the signature of the method to async Task, and try again. Commented Mar 5, 2019 at 9:17
  • Oh, and read this: stackoverflow.com/questions/6982294/… Commented Mar 5, 2019 at 9:22
  • A) don't use async void, B) log any unobserved exceptions, C) try running this in a console app before you commit to a service its easyer to debug,
    – TheGeneral
    Commented Mar 5, 2019 at 9:34

2 Answers 2

7

When calling your start() method, the code instantly continues and OnStart completes. There is now no part of your own code that is able to catch any exceptions. Exceptions will have to be caught by the TaskScheduler. But this will only happen when the Task is awaited or garbage collected.

So basically, your code will have probably thrown an Exception that remains unobserved until the Task is garbage collected. In order to catch an log exceptions sooner, always make sure you catch exceptions inside the method that is not awaited anywhere:

protected override void OnStart(string[] args)
{
    Start();

    // This method finishes immediately (or at least after your first 
    // 'await' in the Start() method. That does not mean Start() runs 
    // on another thread however.
}

private async Task Start()
{
    try
    {
        //initialization things
        ...
        ...
        TcpListener listener = new TcpListener(IPAddress.Any, port);
        listener.Start();
        while(true)
        {
            TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
            ...
        }
        ...   
    }
    catch (Exception ex)
    {
        // TODO: LOG! And probably stop the service too.
    } 
}
2
  • Although this was not my problem, this answer helps me improve the code, thank you
    – ammcom
    Commented Mar 5, 2019 at 10:48
  • Still no exceptions logged? Commented Mar 5, 2019 at 10:54
0

It seems it is a problem in Windows firewall, when I test my code as a console application, I had a confirmation message from Windows firewall to ask for permission to open the port, but when I test it as a service, firewall silently blocked the incoming connections without any notification.

Not the answer you're looking for? Browse other questions tagged or ask your own question.