[英]BackgroundService Graceful Shutdown - Complete work and write to DB
我有一個實現 BackgroundService(由 MS 提供)的后台工作人員。
看這個簡單的實現:
public class MyService : BackgroundService {
private readonly MyDbContext _context;
public MyService(MyDbContext context) {
//...
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try {
while (true)
{
stoppingToken.ThrowIfCancellationRequested();
// Do some work
}
} catch(OperationCancelledException) {
_context.Add(new MyLogMessage(){ Error = "MyService cancelled!" });
_context.SaveChanges();
}
// ...
}
}
當請求正常關閉(在控制台中:CTRL+C)時,觸發了 catch 塊,並且SaveChanges()
似乎也被執行了。 但是,有時錯誤會存儲到數據庫中,而大多數情況下不會。 EntityFramework 也在控制台上打印插入語句,但日志不在數據庫中。 我假設關閉速度比將數據寫入數據庫更快? 誰能給我一個提示如何處理這種情況並將錯誤存儲到數據庫中?
當應用程序關閉時,似乎stoppingToken
沒有按預期取消。 我設法使用IHostApplicationLifetime
和一個新字段來解決這個問題,如果正在進行關機,我可以在其中存儲。
public class TestService : BackgroundService {
private readonly IHostApplicationLifetime _lifetime;
private readonly ILogger<TestService> _logger;
private bool _shutownRequested;
public TestService(IHostApplicationLifetime lifetime, ILogger<TestService> logger) {
_lifetime = lifetime;
_logger = logger;
}
public override Task StartAsync(CancellationToken cancellationToken) {
_lifetime.ApplicationStopping.Register(OnShutdown);
return Task.CompletedTask;
}
private void OnShutdown() {
_shutdownRequested = true;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
try {
while(true) {
stoppingToken.ThrowIfCancellationRequested();
if(_shutdownRequested) {
throw new OperationCanceledException();
}
await Task.Delay(100, CancellationToken.None);
}
} catch(OperationCanceledException) {
_logger.LogWarning("TestService canceled");
}
}
}
現在最好現在在那里拋出一個新的異常,但作為一個例子,它會這樣做。
日志條目沒有出現在數據庫中的原因是主機關閉時間低於在while
循環中處理任務並將日志發送到數據庫所需的時間。 默認超時為 5 秒。
您可以做的是將超時增加到更大的值,例如一分鍾一兩:
services.Configure<HostOptions>(
opts => opts.ShutdownTimeout = TimeSpan.FromMinutes(2));
確保讓服務有足夠的時間在while
循環內完成迭代並記錄消息。
請檢查擴展關閉超時設置以確保 IHostedService 正常關閉以了解更多詳細信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.