为什么在后台工作项目.net6中使用IOptionsSnapshot或IOptionsMonitor时配置值没有更新?

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

未使用 IOptionsSnapshot 或 IOptionsMonitor、使用 .net6 和辅助服务模板获取配置的更新状态。

我已经开始在 .net6 中使用 Workers 进行测试。

我的问题是,我一直在配置设置中工作,一切都很好......直到我需要获取配置文件的更新状态以延迟或继续我的工作人员必须执行的过程。

这是我的代码文件:

程序.cs

var builder = Host.CreateDefaultBuilder();

// Config
builder.ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) =>
{
    configurationBuilder.AddJsonFile(
        ConfigurationConstants.AppSettingsFileLocation,
        optional: false,
        reloadOnChange: true
    );

    var env = hostBuilderContext.HostingEnvironment;
    configurationBuilder
        .AddJsonFile(
            ConfigurationConstants.AppSettingsFileLocation,
            optional: false,
            reloadOnChange: true
        )
        .AddJsonFile(
            $"./Configuration/environments/environment.{env.EnvironmentName}.json",
            optional: false,
            reloadOnChange: true
        );

    var configuration = configurationBuilder.Build();
});

// Services
builder.ConfigureServices((hostBuilderContext, services) =>
{
    services.AddHostedService<Worker>();
    services.AddScoped<MessageRouterProcess, MessageRouterProcess>();
    services.AddTransient<IQueueManager, RabbitMQQueueManagerAdapter>();

    services.Configure<WorkerConfiguration>(hostBuilderContext.Configuration.GetSection(nameof(WorkerConfiguration)));
});

var host = builder.Build();

await host.RunAsync();

Worker.cs

这将运行业务逻辑服务,即“MessageRouterProcess.cs”

namespace Meloons.Whatsapp.Worker.MessageRouter
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        public IServiceProvider Services { get; }

        public Worker(
            IServiceProvider serviceProvider,
            ILogger<Worker> logger
        )
        {
            Services = serviceProvider;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("Consume Scoped Service Hosted Service running.");

            await DoWork(stoppingToken);
        }

        private async Task DoWork(CancellationToken stoppingToken)
        {
            _logger.LogInformation("Consume Scoped Service Hosted Service is working.");

            using (var scope = Services.CreateScope())
            {
                var scopedProcessingService =
                    scope.ServiceProvider
                        .GetRequiredService<MessageRouterProcess>();

                await scopedProcessingService.RouteMessages();
            }
        }
    }
}

业务逻辑

MessageRouterProcess.cs

在此文件中,在 while 循环内,我进行了此验证:“if (!this.Configuration.Lecture)”。 这会获取一个 Config 值,并根据该值,我的工作人员将延迟并跳过循环的当前迭代(因此业务逻辑不会执行)或将运行所有流程。

namespace Meloons.Whatsapp.WebAPI.Core
{
    public class MessageRouterProcess
    {
        protected WorkerConfiguration Configuration;
        private IQueueManager queueManager;

        private readonly HttpClient _httpClient;

        public MessageRouterProcess(
            IQueueManager queueManager,
            IOptionsMonitor<WorkerConfiguration> configuration
        )
        {
            this.Configuration = configuration.CurrentValue;
            configuration.OnChange(updatedConfig =>
            {
                this.Configuration = updatedConfig;
            });

            this.queueManager = queueManager;
            _httpClient = new HttpClient();
        }

        public async Task RouteMessages()
        {
            while (true)
            {
                //bool lecture = bool.Parse(Configuration.GetSection("WorkerConfiguration")["Lecture"]);
                //int TPS = int.Parse(Configuration.GetSection("WorkerConfiguration")["TPS"]);
                //string OutboundQueue = Configuration.GetSection("WorkerConfiguration")["OutboundQueue"];

                if (!this.Configuration.Lecture)
                {
                    await Task.Delay(1000);
                    continue;
                };

                var messageAmountToConsume = this.Configuration.TPS; // Start amount
                var now = DateTime.UtcNow;

                List<Message> messages = await this.queueManager.FetchItem<Message>(messageAmountToConsume);

                this.queueManager.Publish(messages, this.Configuration.OutboundQueue);

                var endDate = DateTime.UtcNow;

                TimeSpan timestamp = endDate - now;
                int timeGap = (int)timestamp.TotalMilliseconds;

                if (1000 - timeGap > 0)
                    await Task.Delay(1000 - timeGap);
            }
        }
    }
}

在本例中,我的代码使用 IOptionsMonitor (不起作用),但在过去我也尝试过使用 IOptionsSnapshot,但也不起作用。

我会继续关注正在发生的事情,但我非常感谢您对此的看法,并知道我忘记了什么。

谢谢:D

c# .net configuration worker ioptionsmonitor
1个回答
0
投票

也许这是为了 AddHostedService。 AddHostedService 与 AddSingleton 类似,在 App 启动时创建该类的实例。 你可以使用:

JObject o1 = JObject.Parse(File.ReadAllText("appsettings.json"));
o1["Log"]!["Size"]!.ToString()
© www.soinside.com 2019 - 2024. All rights reserved.