如何在 .net core 3.0 中执行一次工作服务?

Sam*_*r.B 2 c# background-service .net-core .net-core-3.0

我在 .net core 3.0 中使用了 service worker 模板。如果我的参数“ExecuteOnce”在 appsettings.json 中设置为 true,我想要做的是只执行一次该服务。

程序.cs:

public class Program
    {
        public static IServiceProvider Services { get; set; }
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostContext, config) =>
                {
                    if (hostContext.HostingEnvironment.IsProduction())
                        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                    else
                        config.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true);

                    config.SetBasePath(Directory.GetCurrentDirectory());
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });
        public static void Main(string[] args)
        {
                CreateHostBuilder(args).Build().Run();
        }
    }
Run Code Online (Sandbox Code Playgroud)

工人.cs:

public class Worker : BackgroundService
    {
        private readonly IConfiguration _configuration;
        public Worker(ILogger<Worker> logger, IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public override Task StartAsync(CancellationToken cancellationToken)
        {
            return base.StartAsync(cancellationToken); ;
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            return base.StopAsync(cancellationToken);
        }

        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                // Bit of logic here...

                if (_configuration.GetValue<bool>("TaskConfig:ExecuteOnce"))
                    // TODO HERE : stop this service
                else
                    await Task.Delay(_configuration.GetValue<int>("TaskConfig:TaskDelayMs"), new CancellationToken());
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我试过: -awaiting a Task.TaskCompleted -break the loop -calling StopAsync()

但是每次我偶然发现一些限制时,实现这一点的正确方法是什么?

RB.*_*RB. 7

使用IHostApplicationLifetime - 使用它您可以告诉您的应用程序自行关闭。

public class Worker : BackgroundService
{
    private readonly IHostApplicationLifetime _hostLifetime;

    public Worker(IHostApplicationLifetime hostLifetime) 
    {
        _hostLifetime = hostLifetime;    
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (true)
        {
            DoWork();
            if (RunOnlyOnce())
            {
                _hostLifetime.StopApplication();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)