gpt4 book ai didi

c# - BackgroundService Graceful Shutdown - 完成工作并写入数据库

转载 作者:行者123 更新时间:2023-12-05 01:26:46 32 4
gpt4 key购买 nike

我有一个后台 worker 实现了 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 block ,并且似乎还执行了 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");
}
}
}

现在在那里抛出一个新的异常可能会更好,但作为一个例子它会这样做。

关于c# - BackgroundService Graceful Shutdown - 完成工作并写入数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70036809/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com