C #, вызов асинхронного метода внутри OnStart службы Windows - PullRequest
0 голосов
/ 05 марта 2019

Я разрабатываю службу Windows, которая может принимать сокетное соединение, поэтому в методе OnStart:

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

Функция start выглядит следующим образом:

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

Проблема в том, что соединение не принимается, хотя тот же код отлично работает в стандартном проекте командной строки, я сомневаюсь, что в моем проекте есть проблема: какой поток запускает метод OnStart?, Когда управление возвращается к OnStartпосле await процесса принятия игнорируется ли асинхронный метод, поскольку это особый случай в службе Windows?Любые предложения приветствуются

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Кажется, это проблема в брандмауэре Windows, когда я тестирую свой код как консольное приложение, я получаю сообщение о подтверждении от брандмауэра Windows, чтобы запросить разрешение на открытие порта, но когда я тестирую его как службу, брандмауэрмолча заблокировал входящие соединения без какого-либо уведомления.

0 голосов
/ 05 марта 2019

При вызове метода start () код мгновенно продолжается и OnStart завершается.Теперь в вашем собственном коде нет части, способной перехватывать любые исключения.Исключения должны быть перехвачены TaskScheduler.Но это произойдет только тогда, когда задача будет ожидаемой или сборщик мусора.

Таким образом, в основном ваш код, вероятно, будет выдавать Exception, который останется незамеченным до тех пор, пока Task не будет собран сборщиком мусора.Чтобы быстрее отлавливать исключения из журнала, всегда проверяйте наличие исключений внутри метода, который нигде не ожидается:

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.
    } 
}
...