工人服务意外停止工作 [英] Worker service stops working unexpectedly

查看:37
本文介绍了工人服务意外停止工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有.NET Core 3+工作程序服务,用于检查某些内容",每10秒.在某一时刻,它随机地"被发送给用户.停止这样做了,我不确定为什么.到目前为止,它发生了两次,并且没有异常日志或类似的东西,所以我只能假设我应该在ExecuteAsync内添加一个 try-catch ,但是我的问题是:是否存在任何已知问题可能会导致工人停止执行的类似行为?

I have .NET Core 3+ worker service that checks "some stuff" every 10 seconds. At one point, it "randomly" stopped doing that and I am not sure why. So far it happened twice and there are no exception logs or anything like it, so I can only assume that I should add a try-catch inside ExecuteAsync, but my question is: Are there any known issues that could cause a similar behavior where the worker just stops executing?

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

And yes, there was no cancellation requested (else, I suppose it would log the message "Sender is stopping").

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,但是我的问题是:是否存在任何可能导致类似情况的已知问题工人只是停止执行的行为?

So far it happened twice and there are no exception logs or anything like it, so I can only assume that I should add a try-catch inside ExecuteAsync, but my question is: Are there any known issues that could cause a similar behavior where the worker just stops executing?

这听起来绝对是我的一个例外.默认情况下, BackgroundService 实现将忽略 ExecuteAsync 引发的所有异常.如果 ExecuteAsync 引发了异常,则将忽略该异常,并且该服务将停止运行.

It definitely sounds like an exception to me. By default, the BackgroundService implementation will ignore any exceptions thrown from ExecuteAsync. If an exception is raised from ExecuteAsync, it is ignored and the service just stops running.

我总是建议使用日志记录的顶级 try / catch ,以便您至少知道会发生这种情况:

I always recommend a top-level try/catch with logging, so that you're at least aware that this happens:

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");
  }
}

在相关说明中,如果这是您认为关键"的内容,后台服务,那么您还想在此情况下停止应用程序主机服务停止:

On a related note, if this is what you would consider a "critical" background service, then you would also want to stop the application host when this service stops:

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();
  }
}

这篇关于工人服务意外停止工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆