我正在构建一个 ASP.NET Web API (.NET 5)。除了拥有典型的控制器之外,我还希望有一个始终并行运行的后台作业。为此,我创建了一个托管服务:
public class MyHostedService : IHostedService
{
private readonly IHostApplicationLifetime _appLifetime;
private readonly ILogger _logger;
public MyHostedService(IHostApplicationLifetime appLifetime, ILogger<MyHostedService> logger)
{
_appLifetime = appLifetime ?? throw new ArgumentNullException(nameof(appLifetime));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public Task StartAsync(CancellationToken cancellationToken)
{
return Task.Factory.StartNew(async () =>
{
await Run(cancellationToken);
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
private async Task Run(CancellationToken cancellationToken)
{
try
{
// some long running code
}
catch (OperationCanceledException)
{
_logger.LogInformation("Application was terminated from the outside");
_appLifetime.StopApplication();
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception!");
_appLifetime.StopApplication();
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogDebug("StopAsync executes");
return Task.CompletedTask;
}
}
我注册了它ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo {Title = "My API", Version = "v1"});
});
services.AddHostedService<CacheManagerHostedService>();
}
API 工作正常,MyHostedService
实例运行正常。中的代码StartAsync
启动了一个新线程。如果我不这样做,API 服务器根本不会开始监听。我注意到当我按下 CTRL+C 时应用程序几乎立即关闭。StopAsync
永远不会写入日志。我希望以后能够进行一些清理StopAsync
。我应该改变什么?