重新启动失败的BackgroundService

问题描述 投票:0回答:1

所以我有一个看起来像这样的后台服务。

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 */}
        });

    }
}
c# asp.net-core backgroundworker background-service
1个回答
3
投票

你可以这样编写主循环:

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,这样你就不必手动进行延续和错误检查。

© www.soinside.com 2019 - 2024. All rights reserved.