我有一个需要在 IHostedService 后台任务遇到某种情况时终止的程序。我希望通过在后台任务中抛出异常来实现这一点,该异常会被传递到主函数。然后我可以触发取消令牌以终止其他后台任务。
我的问题是,当我抛出异常时,它只会停止该任务,而其他部分仍然在运行。是否有办法做到这一点,或者有更好的方法来实现我想要的功能?是否有另一种方式让后台任务触发常规的 CancellationToken?
我在下面的代码中包含了我问题的简化版本。如果我注释掉
注意:在我混乱的代码中,我有更多的 IHostedServices 在运行,这就是为什么我试图触发
我的问题是,当我抛出异常时,它只会停止该任务,而其他部分仍然在运行。是否有办法做到这一点,或者有更好的方法来实现我想要的功能?是否有另一种方式让后台任务触发常规的 CancellationToken?
我在下面的代码中包含了我问题的简化版本。如果我注释掉
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
这行代码,那么异常就会按预期执行,并且我可以触发 CancellationToken。但是如果保留该行代码,则该任务会停止,但程序不会停止。注意:在我混乱的代码中,我有更多的 IHostedServices 在运行,这就是为什么我试图触发
cancelSource.Cancel()
的原因。public class Program
{
public static async Task Main(string[] args)
{
using (var cancelSource = new CancellationTokenSource())
{
try
{
await new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<TestService>();
})
.Build()
.RunAsync(cancelSource.Token);
}
catch (Exception E)
{
cancelSource.Cancel();
}
}
}
}
public class TestService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
Console.WriteLine("loop 1");
throw new ApplicationException("OOPS!!");
}
}
}
IApplicationLifetime
已被弃用,推荐使用IHostApplicationLifetime
。 - cudima