Управление отменой токена в .NET Core 3.0 Worker Service - PullRequest
0 голосов
/ 05 ноября 2019

Я разрабатываю свою первую рабочую службу .NET Core 3.0 для ее запуска в качестве службы Windows.

Здесь приведен код, который я использовал для теста.

Отладка Я вижу, чтоПри остановке службы Windows будет выполняться StopAsync (), но ExecuteAsync () завершается из-за исключения OperationCanceledException (выбрасывается из строки Task.Delay (1000, stoppingToken)). Конечно, я могу его поймать, но я хотел бы завершить поток методов, чтобы завершить работу корректно.

Есть ли способ избежать исключения и просто выйти в соответствии с условием while?

namespace Enerj.MyAppCore.WorkerService
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        bool exit = false;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
            _logger.LogInformation("ctor");
        }

        public override async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Start");
            await base.StartAsync(cancellationToken);
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
            System.Diagnostics.Debugger.Break();
        }

        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Stopping");
            await Task.CompletedTask;
        }
    }
}

РЕДАКТИРОВАТЬ ДЛЯ МОЕГО РЕШЕНИЯ. Как видно из кода, приложение тратит почти все время на Task.Delay, поэтому правильно, что исключение выдается из этого кода. Я изменил код следующим образом.

while (!stoppingToken.IsCancellationRequested)
{
    _logger.LogInformation($"Worker running at: {DateTime.Now}");

    try
    {
        await Task.Delay(1000, stoppingToken);
    }
    catch (Exception exc)
    {
        _logger.LogError($"Error running at: {DateTime.Now}");
    }

    System.Diagnostics.Debugger.Break();

    // Other code
}
...