Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过向.net core中的API发布工作程序,轻松发送多个appsettings.json值?_C#_Json_.net Core_Service Worker - Fatal编程技术网

C# 通过向.net core中的API发布工作程序,轻松发送多个appsettings.json值?

C# 通过向.net core中的API发布工作程序,轻松发送多个appsettings.json值?,c#,json,.net-core,service-worker,C#,Json,.net Core,Service Worker,我正在.NETCore3.1中构建一个C#Windows服务API轮询应用程序。这将在服务器上全天候运行,每5分钟轮询一次 我希望通过API post调用发送参数的方法更简单,直接从appsettings.json的主体发送值,而不是为我将轮询的每个对象创建新类和强类型 我的应用程序当前使用一个appsettings对象,给出以下代码: "PollingSettings": { "ReceiptSettings": { "select_topx": "100",

我正在.NETCore3.1中构建一个C#Windows服务API轮询应用程序。这将在服务器上全天候运行,每5分钟轮询一次

我希望通过API post调用发送参数的方法更简单,直接从appsettings.json的主体发送值,而不是为我将轮询的每个对象创建新类和强类型

我的应用程序当前使用一个appsettings对象,给出以下代码:

"PollingSettings": {
    "ReceiptSettings": {
      "select_topx": "100",
      "tran_type": "REC",
      "sub_type": "PO",
      "max_age_min": "10000",
      "integration_name": "ERP"
    },
    "InventorySettings": {
      "select_topx": "100",
      "tran_type": "IN",
      "sub_type": "ADJ",
      "mark_pickup_id": "1"
    }
appsettings.json

    "ReceiptSettings": {
      "select_topx": "100",
      "tran_type": "REC",
      "sub_type": "PO",
      "max_age_min": "10000",
      "integration_name": "ERP"
    }
工人:

        public IConfiguration _configuration { get; private set; }

        ...

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Hosted Service running.");

            _timer = new Timer(DoWork, Task.CompletedTask, TimeSpan.Zero,
                 TimeSpan.FromMinutes(5));

            await Task.CompletedTask;
        }

        private async void DoWork(object state)
        {

            // Keep garbage collector from collecting and stopping timer
            GC.KeepAlive(_timer);

            // Don't let timer execute again if we are still processing last iteration
            if (Monitor.TryEnter(_locker))
            {
                try
                {
                   RunPoller();
                }
                finally
                {
                    Monitor.Exit(_locker);
                }
            }
        }

        private async void RunPoller()
        {
            var count = Interlocked.Increment(ref executionCount);

            // Do long running work here
            _logger.LogInformation($"Polling started. Iteration: {count}");
            await Task.Run(() => RunPoller.Run(_logger, _apiSettings, _configuration));

        }

RunPoller:

        public static IConfiguration _iConfiguration { get; private set; }

        public static async Task Run(ILogger<Worker> logger, IOptions<APIConfiguration> apiSettings, IConfiguration configuration)
        {

        ...

            try
            {
                Dictionary<string, object> settings = _config
                    .GetSection("ReceiptSettings")
                    .Get<Dictionary<string, object>>();
                string json = JsonConvert.SerializeObject(_settings);
                var payload = new StringContent(json, Encoding.UTF8, "application/json");
                ...
            }

        ...
我已经有了强类型的API设置,可以做到这一点。但我必须在VisualStudio中的对象和类中保持更改。如果我通过这个方法动态地发送它们,那么我就可以在记事本中打开appsettings.json文件并在更短的时间内修改参数

我已经尝试过了,但是我得到了空值错误,并且第一次迭代没有处理RunPoller类:

        private async void DoWork(object state)
        {

            // Keep garbage collector from collecting and stopping timer
            GC.KeepAlive(_timer);

            var pollingConfigs = Configuration.GetSection("PollingSettings").GetChildren();

            // Don't let timer execute again if we are still processing last iteration
            if (Monitor.TryEnter(_locker))
            {
                try
                {
                    foreach (var setting in pollingConfigs)
                    {
                        Dictionary<string, object> settings = Configuration
                                                               .GetSection(setting.Key)
                                                               .Get<Dictionary<string, object>>();
                        RunPoller(settings);
                    }
                }
                finally
                {
                    Monitor.Exit(_locker);
                }
            }
        }

        private async void RunPoller(Dictionary<string, object> settings)
        {

            // Do long running work here
            _logger.LogInformation($"Polling started. Iteration: {count}");
            await Task.Run(() => RunPoller.Run(_logger, _apiSettings, settings));

        }

private异步void DoWork(对象状态)
{
//防止垃圾收集器收集和停止计时器
GC.KeepAlive(_定时器);
var pollingConfigs=Configuration.GetSection(“PollingSettings”).GetChildren();
//如果我们仍在处理最后一次迭代,不要让计时器再次执行
if(监视器TryEnter(_locker))
{
尝试
{
foreach(轮询配置中的var设置)
{
字典设置=配置
.GetSection(设置.Key)
.Get();
运行轮询器(设置);
}
}
最后
{
监视器。退出(_locker);
}
}
}
专用异步void RunPoller(字典设置)
{
//在这里做长期工作
_logger.LogInformation($“轮询已开始。迭代:{count}”);
wait Task.Run(()=>RunPoller.Run(_logger,_apiSettings,settings));
}
(将设置的DI持久化到RunPoller.Run,为简洁起见,代码已删除。)


有什么方法可以正确执行此操作吗?

对于现有代码,您可以更改路径以获取子节,如以下代码:
1-通过
路径
更改
,用于
.GetSection(setting.Key)

var pollingConfigs = Configuration.GetSection("PollingSettings").GetChildren();

// Don't let timer execute again if we are still processing last iteration
if (Monitor.TryEnter(_locker))
{
    try
    {
        foreach (var setting in pollingConfigs)
        {
            Dictionary<string, object> settings = Configuration
                                                   .GetSection(setting.Path)
                                                   .Get<Dictionary<string, object>>();
            RunPoller(settings);
        }
    }
    finally
    {
        Monitor.Exit(_locker);
    }
}
var pollingConfigs=Configuration.GetSection(“PollingSettings”).GetChildren();
//如果我们仍在处理最后一次迭代,不要让计时器再次执行
if(监视器TryEnter(_locker))
{
尝试
{
foreach(轮询配置中的var设置)
{
字典设置=配置
.GetSection(设置.Path)
.Get();
运行轮询器(设置);
}
}
最后
{
监视器。退出(_locker);
}
}
2-您也可以使用此解决方案:
2.1获取
词典列表

var pollingConfigs=\u configuration.GetSection(“PollingSettings”)
.GetChildren()
.Select(y=>y.Get());
2.2在循环中,直接使用列表中的值:

foreach (Dictionary<string, object> setting in pollingConfigs)
{
    RunPoller(setting);
}
foreach(pollingConfigs中的字典设置)
{
运行轮询器(设置);
}
我希望这对你有帮助

foreach (Dictionary<string, object> setting in pollingConfigs)
{
    RunPoller(setting);
}