我如何(优美地)从自身内部关闭工人服务?

问题描述 投票:1回答:2

我正在使用.NET Core 3.1辅助服务模板来构建Windows服务。

我认为基本流程应在ExecuteAsync之内处理,大致如此:

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    _Logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);

                    await SomeMethodThatDoesTheWork(stoppingToken);
                }
                catch (Exception ex)
                {
                    _Logger.LogError(ex, "Global exception occurred. Will resume in a moment.");
                }

                await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
            }
        }

我正在尝试从进程中正确发出要关闭应用程序的信号。

[停止服务时,我假设StopAsync()被调用。这似乎很好。因此,我认为await StopAsync()可以解决问题,但是之后ExecuteAsync仍然保持运行状态(因此,我猜想StopAsync不会要求取消,并且您不应该自己叫它)。

所以我用另一个布尔值修改了循环:

            while (!stoppingToken.IsCancellationRequested && !_ShuttingDown)

这确实退出循环,并且再也不会输入ExecuteAsync。但是,该应用程序仍在继续运行。根据调试器,它只是停留在host.Run()上。

我如何向应用程序主机发出要关闭的信号?

c# asp.net .net-core
2个回答
1
投票

在ASP.NET Core中,后台服务独立于应用程序。例如,服务可能会完成,但应用程序仍会继续执行。如果您希望在后台服务完成时退出应用程序,则需要自行进行连接。

您可以将IHostApplicationLifetime注入您的服务,然后呼叫IHostApplicationLifetime.StopApplication。像这样的东西:

public sealed class MyService : BackgroundService
{
  private readonly IHostApplicationLifetime _hostApplicationLifetime;
  private readonly ILogger<MyService> _logger;

  public MyService(IHostApplicationLifetime hostApplicationLifetime, ILogger<MyService> logger)
  {
    _hostApplicationLifetime = hostApplicationLifetime;
    _logger = logger;
  }

  protected override Task ExecuteAsync(CancellationToken stoppingToken)
  {
    try
    {
      while (!stoppingToken.IsCancellationRequested)
      {
        try
        {
          _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
          await SomeMethodThatDoesTheWork(stoppingToken);
        }
        catch (Exception ex)
        {
          _logger.LogError(ex, "Global exception occurred. Will resume in a moment.");
        }

        await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
      }
    }
    finally
    {
      _logger.LogCritical("Exiting application...");
      _hostApplicationLifetime.StopApplication();
    }
  }
}

0
投票

服务不应该停止自身,它们不是应用程序-它们是服务...

为什么要从服务内部停止服务?也许您想要预定的任务而不是服务。

您总是可以使用ServiceController或类似的类将stop事件发送到服务

© www.soinside.com 2019 - 2024. All rights reserved.