重新启动失败的BackgroundService



这个后台服务看起来是这样的

public class MyBackgroundService: BackgroundService
{ 
public MyBackgroundService(){}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
new Thread(() => new MessageHandler().Process(stoppingToken).Start();
return Task.CompletedTask;
}      
}

如果Process-method会抛出异常,是否可以尝试重新启动还是创建一个新的MessageHandler并运行Process?

编辑经过反馈和谷歌搜索,我想到了这样的东西

protected override Task ExecuteAsync(CancellationToken cancellationToken)
{       
Task.Run(()=>RunConsumer(cancellationToken)).Start();
return Task.CompletedTask;
}
private void RunConsumer(CancellationToken cancellationToken)
{
while (true)
{
using var scope = _serviceScopeFactory.CreateScope();
var myConsumer= scope.ServiceProvider.GetRequiredService<IMyConsumer>();
Task.Run(() =>{new Thread(() => myConsumer.Start()).Start();})
.ContinueWith(t =>
{
if (t.IsFaulted) {/* Log t.Exception and retry x times */}
if (t.IsCompleted) {/* Should not not happen in my case */}
});
}
}

你可以这样写主循环:

protected override Task ExecuteAsync(CancellationToken cancellationToken)
{
while(!cancellationToken.IsCancellationRequested) 
{
try {
await RunConsumer(cancellationToken);
}
catch (Exception e)
{
// log exception
}
await Task.Delay(TimeSpan.FromSeconds(30)); // To prevent restarting too often
}
return Task.CompletedTask;
}

关键是

  • 通过检查cancellationToken.IsCancellationRequested,服务将在被请求时停止,例如当进程正常结束时,
  • 捕获所有异常并忽略它,以便任务可以再次运行。
  • Task.Delay确保进程不会太频繁地重启。

RunConsumer中,您可以使用

await Task.Run(() => new MessageHandler().Process(stoppingToken).Start());

通常最好使用async/await,这样你就不必手动执行延续和错误检查了。

最新更新