后台任务的全局异常处理

时间:2019-06-12 04:42:40

标签: c# asp.net-core scheduled-tasks

我一直在从事.net Core api项目,并根据此示例(在解决方案中)here实施了后台任务。 我已经在我的api控制器上使用了一些全局异常处理,并且根据要求,我必须删除所有try catch语句并改为提供简单的HttpStatusCodes。

我需要对我的一个或多个后台任务执行相同的操作,方法是创建一个可从任何其他类继承的全局Exception处理类,并通过记录该异常而不会使其系统崩溃来处理其“魔术”。我还必须避免每个请求的try / catch语句。

到目前为止,我的代码 HostedService

ID:empty{display: None}

AsyncTask实现

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();
        }
    }

我的过滤器

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


        }

以及我在服务中的Startup.cs中

public class CustomExceptionFilter : IExceptionFilter
{

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

我期望通过向系统抛出一个异常以使其进入'OnException'方法并执行其工作,但事实并非如此。

这里的结构有什么问题? 是否不可能从继承自IExceptionFilter的任何服务中捕获任何异常? 如果有人可以提供异常过滤器的基本实现以用于我的后台任务而无需try / catch,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

过滤器和中间件仅可用于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