如何在运行时从 appsettings.json 读取 CRON 表达式?
How to read the CRON expression from appsettings.json at runtime?
我开发了具有多个定时器触发功能的网络作业项目。每个功能在一天中的不同时间执行。有的每分钟执行一次,有的每五分钟执行一次,有的一天执行一次。
如果我在函数参数属性本身中写 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.
读取时间表的写法
是的。不要硬编码 CRON 表达式,而是将表达式放在应用程序设置中并使用 %
符号引用它。例如,如果您有一个名为 CRON_EXPRESSION
:
的设置
public static void 运行([TimerTrigger("%CRON_EXPRESSION%")]TimerInfo myTimer, TraceWriter 日志)
参考 - https://github.com/Azure/azure-functions-host/issues/1934
我开发了具有多个定时器触发功能的网络作业项目。每个功能在一天中的不同时间执行。有的每分钟执行一次,有的每五分钟执行一次,有的一天执行一次。
如果我在函数参数属性本身中写 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.
是的。不要硬编码 CRON 表达式,而是将表达式放在应用程序设置中并使用 %
符号引用它。例如,如果您有一个名为 CRON_EXPRESSION
:
public static void 运行([TimerTrigger("%CRON_EXPRESSION%")]TimerInfo myTimer, TraceWriter 日志)
参考 - https://github.com/Azure/azure-functions-host/issues/1934