該賞金到期in 4天。回答這個問題有資格獲得 50聲望獎勵。 Zar正在尋找規范的答案。
我有一個后臺作業人員實作了 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 正在控制臺上列印插入陳述句,但日志不在資料庫中。我假設關閉發生得更快,然后將資料寫入資料庫?誰能給我一個提示如何處理這種情況并將錯誤存盤到資料庫中?
uj5u.com熱心網友回復:
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");
}
}
}
現在最好在那里拋出一個新的例外,但作為一個例子,它會這樣做。
uj5u.com熱心網友回復:
日志條目沒有出現在資料庫中的原因是主機關閉時間低于while回圈處理任務并將日志發送到資料庫所需的時間。默認超時為 5 秒。
您可以做的是將超時增加到更大的值,例如一分鐘一兩:
services.Configure<HostOptions>(
opts => opts.ShutdownTimeout = TimeSpan.FromMinutes(2));
確保有足夠的時間讓服務在回圈內完成迭代while并記錄訊息。
請檢查延長關閉超時設定以確保 IHostedService 正常關閉以獲取更多詳細資訊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/363150.html
