Global Exception Handling for Background tasks

会有一股神秘感。 提交于 2021-02-08 04:48:04

问题


I have been working on a .net Core api project and I implemented a background task based on this example (in solution) here . I am already using some Global Exception handling for my api controllers, and by requirement I had to remove all the try catch statements and give simple HttpStatusCodes instead.

I am required to do the same for my background task/tasks by creating a global Exception handling class to be inherited from any other class and work its "magic" by logging the exception without crashing the system. I also have to avoid try/catch statements per request.

My code so far 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();
        }
    }

The AsyncTask implementation

 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");


        }

My Filter

public class CustomExceptionFilter : IExceptionFilter
{

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

and in my Startup.cs in services

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

I was expecting by throwing an exception for the system to go in the 'OnException' method and do its work, but it didn't.

What is wrong in my structure here? Is it not possible to catch any exception from any services that inherit from IExceptionFilter? I would appreciate it if anyone could provide a basic implementation of an exception filter to be used for my background tasks without try/catch.


回答1:


Filters and Middleware are only available for the MVC-pipeline, a request is required otherwise the pipeline doesn't start. Implementations of IHostedService are triggered by the Host (ASP.NET Core >= 3.0) or WebHost (ASP.NET Core < 3.0) and do not run within the MVC-pipeline.

Classical try{}catch(Exception e) is what you need here.

Some sources: 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



来源:https://stackoverflow.com/questions/56554793/global-exception-handling-for-background-tasks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!