如何在运行时从appsettings.json中读取CRON表达式?

时间:2019-02-19 06:31:26

标签: azure azure-webjobs timer-trigger

我开发了具有多个计时器触发功能的网络作业项目。每个功能在一天的不同时间执行。其中有些每分钟执行一次,有些每五分钟执行一次,有些一天执行一次。

如果我在函数形参属性本身中编写CRON表达式,如
ProcessTrigger2([TimerTrigger("0 */3 * * * *", RunOnStartup = false)]TimerInfo timerInfo),它可以按预期工作,但是当我尝试从appsettings.json中读取时,它失败了。

有人能建议在Functions.cs中阅读appsettings.json的正确方法吗?

以下是我正在尝试的代码。

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 * * * *"
  }
}

在上面的代码中,在Functions.cs中,如果我将计时器触发器写入
ProcessTrigger2([TimerTrigger("0 */3 * * * *", RunOnStartup = false)]TimerInfo timerInfo)对于所有方法都采用这种方式,该工作可以按预期工作,但是如果我以其他两种方式编写,它将给我带来例外。 请提出从appsettings.json中读取时间表的写法。

1 个答案:

答案 0 :(得分:0)

是的。无需对CRON表达式进行硬编码,而是将表达式放在应用程序设置中,并使用%符号进行引用。例如,如果您有一个名为CRON_EXPRESSION的设置:

public static void Run([[TimerTrigger(“%CRON_EXPRESSION%”)] TimerInfo myTimer,TraceWriter日志)

引荐-https://github.com/Azure/azure-functions-host/issues/1934