简体   繁体   English

后台任务的全局异常处理

[英]Global Exception Handling for Background tasks

I have been working on a .net Core api project and I implemented a background task based on this example (in solution) here .我一直在.NET核心API项目,我实现了一个基于这个例子中(在溶液中)后台任务在这里 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.我已经为我的 api 控制器使用了一些全局异常处理,并且根据要求,我必须删除所有 try catch 语句并改为提供简单的 HttpStatusCodes。

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.我还必须避免每个请求的 try/catch 语句。

My code so far The HostedService到目前为止我的代码 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 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");


        }

My Filter我的过滤器

public class CustomExceptionFilter : IExceptionFilter
{

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

and in my Startup.cs in services并在我的 Startup.cs 中的服务

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.我期待通过抛出异常让系统进入 'OnException' 方法并完成它的工作,但它没有。

What is wrong in my structure here?我这里的结构有什么问题? Is it not possible to catch any exception from any services that inherit from IExceptionFilter?是否无法从继承自 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.如果有人可以提供一个异常过滤器的基本实现,用于我的后台任务而无需 try/catch,我将不胜感激。

Filters and Middleware are only available for the MVC-pipeline, a request is required otherwise the pipeline doesn't start.过滤器和中间件仅适用于 MVC 管道,需要一个请求,否则管道不会启动。 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. IHostedService实现由Host (ASP.NET Core >= 3.0) 或WebHost (ASP.NET Core < 3.0) 触发,并且不在 MVC 管道中运行。

Classical try{}catch(Exception e) is what you need here.经典的try{}catch(Exception e)正是您在这里所需要的。

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 : //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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM