BackgroundService崩溃时主机不会停止



请参阅下面的示例代码。我希望当后台服务崩溃时主机会自动停止,但事实并非如此。结果是,Windows服务似乎正在运行,但它不执行任何工作。。。如何确保程序检测到后台服务已停止?

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace WorkerTest
{
public static class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}

public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private int _counter;

public Worker(ILogger<Worker> logger)
{
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time} ({counter})", DateTimeOffset.Now, _counter++);
if (_counter > 10)
throw new Exception("Something happened!");
await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
}
}
finally
{
if (!stoppingToken.IsCancellationRequested)
_logger.LogError("Worker stopped unexpectedly");
}
}
}

}

您可以运行以下操作以确保服务按预期关闭:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time} ({counter})", DateTimeOffset.Now, _counter++);
if (_counter > 10)
throw new Exception("Something happened!");
await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
}
}
catch (Exception)
{
_applicationLifeTime.StopApplication();
}
finally
{
if (!stoppingToken.IsCancellationRequested)
_logger.LogError("Worker stopped unexpectedly");

}
}

为此,您需要将IApplicationLifetime注入BackgroundService

这已经从.NET 6及以后进行了更改。

更改说明

在早期的.NET版本中,当从BackgroundService.ExecuteAsync(CancellationToken(重写引发异常时,主机将继续运行,并且不会记录任何消息。

从.NET 6中启动,当从BackgroundService.ExecuteAsync(CancellationToken(重写引发异常时,该异常将记录到当前ILogger中。默认情况下,当遇到未处理的异常时,主机将停止。

https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/hosting-exception-handling

最新更新