Глобальная обработка исключений для фоновых задач - PullRequest
0 голосов
/ 12 июня 2019

Я работал над проектом .net Core api и реализовал фоновую задачу на основе этого примера (в решении) здесь .Я уже использую некоторую обработку глобальных исключений для моих контроллеров API, и по требованию мне пришлось удалить все операторы try catch и вместо этого дать простые HttpStatusCodes.

Мне необходимо сделать то же самое для моих фоновых задач / задачсоздавая глобальный класс обработки исключений, который будет унаследован от любого другого класса и использовать его «магию», регистрируя исключение, не сбивая систему.Я также должен избегать операторов try / catch для каждого запроса.

Мой код на данный момент The HostedService

public class MyHostedService : CustomExceptionFilter, IHostedService
    {
        private Timer _timer;
        private readonly IServiceScopeFactory _scopeFactory;

        private readonly ILogger _logger;

        public SchedulerHostedService(IServiceScopeFactory scopeFactory)
        {
            _scopeFactory = scopeFactory;

            _logger = new LoggerManager();

        }
        public Task StartAsync(CancellationToken cancellationToken)
        {

            _logger.Info("Background Service is starting");
            _timer = new Timer(ExecuteTask, null, TimeSpan.Zero, TimeSpan.FromMinutes(30));
            return Task.CompletedTask;

        }

        private void ExecuteTask(object state)
        {
            _ = ExecuteTaskOperationAsync();
        }



        private async Task ExecuteTaskOperationAsync()
        {
            using (IServiceScope scope = _scopeFactory.CreateScope())
            {
                IAsyncTask service = scope.ServiceProvider
                    .GetRequiredService<IAsyncTask>();
                await service.CustomTaskAsync();
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.Info("Background Service is stopping");
            _timer?.Change(Timeout.Infinite, 0);
            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }

Реализация AsyncTask

 internal interface IAsyncTask
    {
        Task CustomTaskAsync();
    }


    public class DbInternalOperation : CustomExceptionFilter, IAsyncTask
    {
        private readonly MyDbContext _context;

        private readonly ILogger _logger;
        public DbInternalOperation(MyDbContext context)
        {
            _context = context;

            _logger = new Logger();

        }

        public async Task CustomTaskAsync()
        {

            //All db logic to update some records based on date.           
           throw new Exception("Test");

                _logger.Info($"Scheduled operation started");

               //Some code for dbcontext 
                await _context.SaveChangesAsync();


                _logger.Info($"Scheduled operation finished");


        }

Мой фильтр

public class CustomExceptionFilter : IExceptionFilter
{

    public void OnException(ExceptionContext context)
     {
        //Some logic for handling exceptions.
     }
}

и в моих файлах Startup.cs в службах

services.AddHostedService<MyHostedService>();
services.AddScoped<IAsyncTask, DbInternalOperation >();
services.AddMvc(options=>options.Filters.Add(new CustomExceptionFilter()));

Я ожидал, вызвав исключение для системы, чтобы перейти к методу OnException и выполнить свою работу, но это не так.т.

Что не так в моей структуре здесь?Разве невозможно поймать какое-либо исключение из каких-либо служб, которые наследуются от IExceptionFilter?Буду признателен, если кто-нибудь сможет предоставить базовую реализацию фильтра исключений, который будет использоваться для моих фоновых задач без try / catch.

1 Ответ

1 голос
/ 12 июня 2019

Фильтры и промежуточное ПО доступны только для MVC-конвейера, требуется запрос, иначе конвейер не запускается. Реализации IHostedService запускаются WebHost и не работают в MVC-конвейере.

Классический try{}catch(Exception e) - это то, что вам нужно здесь.

Некоторые источники: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2 https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2

...