C# 辅助服务意外停止工作

C# 辅助服务意外停止工作,c#,.net-core,service-worker,worker,C#,.net Core,Service Worker,Worker,我有.NETCore3+工人服务,每10秒检查一次“一些东西”。有一次,它“随机”停止了这样做,我不知道为什么。到目前为止,它发生了两次,并且没有异常日志或类似的内容,因此我只能假设我应该在ExecuteAsync中添加一个try catch,但我的问题是:是否存在任何已知的问题,可能会导致类似的行为,即工人停止执行 是的,没有请求取消(否则,我想它会记录消息“发件人正在停止”) public class Worker:BackgroundService { 专用只读ILogger\u记录器;

我有.NETCore3+工人服务,每10秒检查一次“一些东西”。有一次,它“随机”停止了这样做,我不知道为什么。到目前为止,它发生了两次,并且没有异常日志或类似的内容,因此我只能假设我应该在ExecuteAsync中添加一个
try catch
,但我的问题是:是否存在任何已知的问题,可能会导致类似的行为,即工人停止执行

是的,没有请求取消(否则,我想它会记录消息“发件人正在停止”)

public class Worker:BackgroundService
{
专用只读ILogger\u记录器;
公共工作者(ILogger记录器)
{
_记录器=记录器;
}
受保护的覆盖异步任务ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(“发送方正在启动”);
stoppingToken.Register(()=>_logger.LogInformation(“发送方正在停止”);
同时(!stoppingToken.IsCancellationRequested)
{
等待任务。延迟(10000,停止待命);
_LogDebug(“在:{time}运行的工作进程”,DateTimeOffset.Now);
如果(!stoppingToken.IsCancellationRequested)
等待SendPendingMessages();
}
}
专用异步任务SendPendingMessages()
{
变量列表=。。。
foreach(列表中的变量项)
{
尝试
{
//按预期做事
}
捕获(例外情况除外)
{
_logger.LogError(例如,例如消息);
}
}
}
}
请注意

await Task.Delay(10000, stoppingToken);
当您触发取消令牌时,将抛出OperationCancelledException,该令牌未经处理

还要确保
LogError()
LogDebug()
有一个catch-all-try块,并且不能抛出自己,这也会破坏代码

看不到其他有问题的东西

到目前为止,它发生了两次,并且没有异常日志或类似的内容,因此我只能假设我应该在ExecuteAsync中添加一个try-catch,但我的问题是:是否存在任何已知的问题,可能会导致类似的行为,即工人停止执行

这对我来说绝对是个例外。默认情况下。如果从
ExecuteAsync
引发异常,将忽略该异常,服务将停止运行

我总是建议您使用顶级的
尝试
/
捕获
,并记录日志,这样您至少会意识到这种情况:

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"); } } 受保护的覆盖异步任务ExecuteAsync(CancellationToken stoppingToken) { _logger.LogInformation(“发送方正在启动”); 尝试 { 同时(!stoppingToken.IsCancellationRequested) { 等待任务。延迟(10000,停止待命); _LogDebug(“在:{time}运行的工作进程”,DateTimeOffset.Now); 如果(!stoppingToken.IsCancellationRequested) 等待SendPendingMessages(); } } 当(stoppingToken.IsCancellationRequested)时捕获(异常ex) { _logger.LogInformation(“发送方正在停止”); } 当(!stoppingToken.IsCancellationRequested)时捕获(异常ex) { _logger.LogError(例如,“发送方有错误”); } }

在一个相关的注释中,如果这是你认为的“临界”背景服务,那么你也会想:

专用只读ILogger\u记录器; 私有只读IHostApplicationLifetime\u hostApplicationLifetime; 公共工作者(ILogger记录器,IHostApplicationLifetime主机ApplicationLifeTime) { _记录器=记录器; _hostApplicationLifetime=hostApplicationLifetime; } 受保护的覆盖异步任务ExecuteAsync(CancellationToken stoppingToken) { _logger.LogInformation(“发送方正在启动”); 尝试 { 同时(!stoppingToken.IsCancellationRequested) { 等待任务。延迟(10000,停止待命); _LogDebug(“在:{time}运行的工作进程”,DateTimeOffset.Now); 如果(!stoppingToken.IsCancellationRequested) 等待SendPendingMessages(); } } 当(stoppingToken.IsCancellationRequested)时捕获(异常ex) { _logger.LogInformation(“发送方正在停止”); } 当(!stoppingToken.IsCancellationRequested)时捕获(异常ex) { _logger.LogError(例如,“发送方有错误”); } 最后 { _hostApplicationLifetime.StopApplication(); } } 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(); } }