这个后台服务看起来是这样的
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,这样你就不必手动执行延续和错误检查了。