【发布时间】:2019-10-26 12:44:12
【问题描述】:
我一直在做一个 .net Core api 项目,我根据这个例子(在解决方案中)here 实现了一个后台任务。 我已经为我的 api 控制器使用了一些全局异常处理,并且根据要求,我必须删除所有 try catch 语句并改为提供简单的 HttpStatusCodes。
我需要为我的后台任务/任务执行相同的操作,方法是创建一个全局异常处理类以从任何其他类继承,并通过记录异常而不使系统崩溃来发挥其“魔力”。我还必须避免每个请求都使用 try/catch 语句。
到目前为止我的代码 托管服务
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,我将不胜感激。
【问题讨论】:
标签: c# asp.net-core scheduled-tasks