Как прочитать выражение CRON из appsettings.json во время выполнения? - PullRequest
0 голосов
/ 19 февраля 2019

Я разработал проект веб-задания, в котором есть несколько функций запуска по таймеру.Каждая функция выполняется в разное время дня.Некоторые из них исполняются каждую минуту, некоторые - каждые пять минут, а некоторые - раз в день.

Если я напишу выражение CRON в самом атрибуте параметра функции, например
ProcessTrigger2([TimerTrigger("0 */3 * * * *", RunOnStartup = false)]TimerInfo timerInfo), оно будет работать, как и ожидалось, но при попытке прочитать его из appsettings.json произойдет сбой.

Может ли кто-нибудь предложить правильный способ чтения appsettings.json в Functions.cs ??

Ниже приведен код, который я пытаюсь выполнить.

Program.cs

internal class Program
   {
        // Please set the following connection strings in app.config for this WebJob to run:
        // AzureWebJobsDashboard and AzureWebJobsStorage
        private static void Main()
        {
            ServiceCollection services = new ServiceCollection();
            ConfigureServices(services);

            var config = new JobHostConfiguration();
            config.JobActivator = new JobActivator(services.BuildServiceProvider());
            config.UseTimers();

            if (config.IsDevelopment)
            {
                config.UseDevelopmentSettings();
            }

            var host = new JobHost(config);
            // The following code ensures that the WebJob will be running continuously
            host.RunAndBlock();
        }

        private static IConfiguration Configuration { get; set; }

        private static void ConfigureServices(IServiceCollection services)
        {
            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            Configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            services.AddSingleton(Configuration);
            services.AddTransient<Functions, Functions>();
            services.AddLogging(builder => builder.AddConsole());
        }
    }

Functions.cs

public class Functions
    {
        private readonly ILogger<Functions> logger;

        private readonly IConfiguration configuration;

        public Functions(ILogger<Functions> logger, IConfiguration configuration)
        {
            this.configuration = configuration;
            this.logger = logger;
        }


        [FunctionName("TimerTriggerEveryMinute")]
        public void ProcessTrigger1([TimerTrigger("%TimerTriggerEveryMinute:Schedule%")]TimerInfo timerInfo)
        {
            var ab = this.configuration;
            Console.WriteLine(string.Format("{0} Proc 1",DateTime.Now));
        }

        [FunctionName("TimerTriggerEveryThirdMinute")]
        public void ProcessTrigger2([TimerTrigger("0 */3 * * * *", RunOnStartup = false)]TimerInfo timerInfo)
        {
            Console.WriteLine(string.Format("{0} Proc 2",DateTime.Now));
        }

        [FunctionName("TimerTriggerEveryFiveMinute")]
        public void ProcessTrigger3([TimerTrigger("%EveryFiveMinuteSchedule%",RunOnStartup =false)]TimerInfo timer)
        {
            Console.WriteLine(string.Format("{0} Proc 5", DateTime.Now));
        }
}

JobActivator.cs

 public class JobActivator : IJobActivator
    {
        private readonly IServiceProvider services;

        public JobActivator(IServiceProvider services)
        {
            this.services = services;
        }

        public T CreateInstance<T>()
        {
            return services.GetService<T>();
        }
    }

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "AzureWebJobsDashboard": "My Azure Dashboard key here...",
    "AzureWebJobsStorage": "My Azure Job Storage key here...",
  },
  "TimerTriggerEveryMinute": {
    "Schedule": "0 * * * * *"
  },
  "TimerTriggerEveryFiveMinute": {
    "Schedule": "0 */5 * * * *"
  }
}

В приведенном выше коде в функциях.cs, если я запишу триггер таймера в
ProcessTrigger2([TimerTrigger("0 */3 * * * *", RunOnStartup = false)]TimerInfo timerInfo) таким образом для всех методов, задание будет работать как положено, но если я напишу двумя другими способами, это даст мне исключение.Пожалуйста, предложите способ записи расписания из appsettings.json.

1 Ответ

0 голосов
/ 19 февраля 2019

Да.Вместо жесткого кодирования выражения CRON, поместите выражение в настройку приложения и обращайтесь к нему с помощью знаков %.Например, если у вас есть параметр с именем CRON_EXPRESSION:

public static void Run ([TimerTrigger ("% CRON_EXPRESSION%")] TimerInfo myTimer, журнал TraceWriter)

См. - https://github.com/Azure/azure-functions-host/issues/1934

...