簡體   English   中英

后台任務的全局異常處理

[英]Global Exception Handling for Background tasks

我一直在.NET核心API項目,我實現了一個基於這個例子中(在溶液中)后台任務在這里 我已經為我的 api 控制器使用了一些全局異常處理,並且根據要求,我必須刪除所有 try catch 語句並改為提供簡單的 HttpStatusCodes。

我需要通過創建一個從任何其他類繼承的全局異常處理類來為我的后台任務/任務做同樣的事情,並通過記錄異常而不使系統崩潰來發揮它的“魔力”。 我還必須避免每個請求的 try/catch 語句。

到目前為止我的代碼 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,我將不勝感激。

過濾器和中間件僅適用於 MVC 管道,需要一個請求,否則管道不會啟動。 IHostedService實現由Host (ASP.NET Core >= 3.0) 或WebHost (ASP.NET Core < 3.0) 觸發,並且不在 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM