我有 .NET Core 3+ 辅助服务,每 10 秒检查“一些内容”。有一次,它“随机”停止这样做,我不确定为什么。到目前为止,它发生了两次,并且没有异常日志或类似的东西,所以我只能假设我应该添加一个try-catch
在 ExecuteAsync 内部,但我的问题是:是否有任何已知问题可能导致工作人员停止执行的类似行为?
是的,没有取消请求(否则,我想它会记录消息“发件人正在停止”)。
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Sender is starting");
stoppingToken.Register(() => _logger.LogInformation("Sender is stopping"));
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(10000, stoppingToken);
_logger.LogDebug("Worker running at: {time}", DateTimeOffset.Now);
if (!stoppingToken.IsCancellationRequested)
await SendPendingMessages();
}
}
private async Task SendPendingMessages()
{
var list = ...
foreach (var item in list)
{
try
{
// Do stuff as expected
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
}
}
}
}
到目前为止,它发生了两次,并且没有异常日志或类似的东西,所以我只能假设我应该在 ExecuteAsync 中添加一个 try-catch,但我的问题是:是否有任何已知问题可能导致类似的行为,其中工人就停止执行?
对我来说这听起来确实是个例外。默认情况下,the BackgroundService实施将ignore抛出的任何异常ExecuteAsync。如果引发异常ExecuteAsync
,它会被忽略,并且服务会停止运行。
我总是推荐顶级的try
/catch
通过日志记录,这样您至少知道发生了这种情况:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Sender is starting");
try
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(10000, stoppingToken);
_logger.LogDebug("Worker running at: {time}", DateTimeOffset.Now);
if (!stoppingToken.IsCancellationRequested)
await SendPendingMessages();
}
}
catch (Exception ex) when (stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Sender is stopping");
}
catch (Exception ex) when (!stoppingToken.IsCancellationRequested)
{
_logger.LogError(ex, "Sender had error");
}
}
与此相关的是,如果这是您认为的“关键”后台服务,那么您还需要当该服务停止时停止应用程序主机:
private readonly ILogger<Worker> _logger;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
public Worker(ILogger<Worker> logger, IHostApplicationLifetime hostApplicationLifetime)
{
_logger = logger;
_hostApplicationLifetime = hostApplicationLifetime;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Sender is starting");
try
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(10000, stoppingToken);
_logger.LogDebug("Worker running at: {time}", DateTimeOffset.Now);
if (!stoppingToken.IsCancellationRequested)
await SendPendingMessages();
}
}
catch (Exception ex) when (stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Sender is stopping");
}
catch (Exception ex) when (!stoppingToken.IsCancellationRequested)
{
_logger.LogError(ex, "Sender had error");
}
finally
{
_hostApplicationLifetime.StopApplication();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)