Почему. NET Core Worker Service имеет два разных поведения исключений в методе ExecuteAsyn c? - PullRequest
0 голосов
/ 16 января 2020

Я создал образец. NET Ниже указано базовое рабочее обслуживание, оно просто сгенерировало исключение.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace DemoWorkerService
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                throw new Exception("My Exception");

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}

Вышеуказанный рабочий процесс обслуживания будет прерван из-за сгенерированного исключения, как и ожидалось.

Затем я изменил исключение, вставленное после оператора await, как показано ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace DemoWorkerService
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

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

                throw new Exception("My Exception");
            }
        }
    }
}

На этот раз рабочий процесс службы все еще продолжается после того, как было сгенерировано исключение, я даже могу остановить процесс в консоль, нажав «Ctrl + C», вот информация журнала:

info: DemoWorkerService.Worker[0]
      Worker running at: 01/16/2020 12:26:07 +08:00
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\MyProjects\DemoWorkerService\DemoWorkerService
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...

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

1 Ответ

1 голос
/ 16 января 2020

Это по замыслу. BackgroundService реализует IHostedService и возвращается из StartAsync только тогда, когда ваша служба начала выполнение .

Если какое-либо IHostedService выдает исключение во время StartAsync, то IHost не запустится.

Поэтому, если ваш BackgroundService сгенерирует до первого ожидания, исключение будет распространяться и давать сбой хосту. Если вы хотите предотвратить это, вы можете сначала позвонить await Task.Yield().

...