BackgroundService 在计划外时间运行
BackgroundService runs on unscheduled times
我有这个后台服务:
public class ReminderService : BackgroundService
{
private readonly int[] reminderDays = { 1, 3, 6, 9 };
protected override async Task ExecuteAsync(CancellationToken stopToken)
{
while (!stopToken.IsCancellationRequested)
{
DateTime now = DateTime.Now;
DateTime start = now.Date.AddHours(13);
if (now > start) start = start.AddDays(1);
await Task.Delay(start.Subtract(now), stopToken);
if (reminderDays.Contains(now.Day)) await DoWork();
}
}
protected async Task DoWork()
{
// The work...
}
}
我希望服务 运行 每个月的第一天、第三天、第六天和第九天的下午 1 点。从我在日志中看到的情况来看,该服务很少 运行 比预期时间晚几毫秒,但通常会晚一天(下午 1 点左右的 2、4、7、10)。
if几乎只能在我的Task.Delay计算中,但我不知道为什么。
我有其他服务运行不同starts/delays但有同样的问题。
谁能看出哪里出了问题?我对其他方法持开放态度,但我不喜欢使用像 Hangfire 这样的库。
你可能会寻找一个调度程序quartz,它非常适合使用非常适合后台调度程序的crontab格式。
如果你想找个轻便的crontab库Cronos
或者NCrontab只能通过crontab获取时间
对于所有这些,我更喜欢使用 Cronos
库,因为它支持 UTC 和夏令时转换。
public class ReminderService : BackgroundService
{
private const string cronExpression= "0 13 1,3,6,9 * *";
private readonly CronExpression _cronJob;
public ReminderService()
{
_cronJob = CronExpression.Parse(cronExpression);
}
protected override async Task ExecuteAsync(CancellationToken stopToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var now = DateTime.UtcNow;
var nextUtc = _cronJob.GetNextOccurrence(now);
await Task.Delay(now - nextUtc.Value, stoppingToken);
await DoWork();
}
}
protected async Task DoWork()
{
// The work...
}
}
这是一个非常棒的网站 cron-expression-generator 帮助我们通过 UI
获取 crontab 表达式
我有这个后台服务:
public class ReminderService : BackgroundService
{
private readonly int[] reminderDays = { 1, 3, 6, 9 };
protected override async Task ExecuteAsync(CancellationToken stopToken)
{
while (!stopToken.IsCancellationRequested)
{
DateTime now = DateTime.Now;
DateTime start = now.Date.AddHours(13);
if (now > start) start = start.AddDays(1);
await Task.Delay(start.Subtract(now), stopToken);
if (reminderDays.Contains(now.Day)) await DoWork();
}
}
protected async Task DoWork()
{
// The work...
}
}
我希望服务 运行 每个月的第一天、第三天、第六天和第九天的下午 1 点。从我在日志中看到的情况来看,该服务很少 运行 比预期时间晚几毫秒,但通常会晚一天(下午 1 点左右的 2、4、7、10)。
if几乎只能在我的Task.Delay计算中,但我不知道为什么。
我有其他服务运行不同starts/delays但有同样的问题。
谁能看出哪里出了问题?我对其他方法持开放态度,但我不喜欢使用像 Hangfire 这样的库。
你可能会寻找一个调度程序quartz,它非常适合使用非常适合后台调度程序的crontab格式。
如果你想找个轻便的crontab库Cronos 或者NCrontab只能通过crontab获取时间
对于所有这些,我更喜欢使用 Cronos
库,因为它支持 UTC 和夏令时转换。
public class ReminderService : BackgroundService
{
private const string cronExpression= "0 13 1,3,6,9 * *";
private readonly CronExpression _cronJob;
public ReminderService()
{
_cronJob = CronExpression.Parse(cronExpression);
}
protected override async Task ExecuteAsync(CancellationToken stopToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var now = DateTime.UtcNow;
var nextUtc = _cronJob.GetNextOccurrence(now);
await Task.Delay(now - nextUtc.Value, stoppingToken);
await DoWork();
}
}
protected async Task DoWork()
{
// The work...
}
}
这是一个非常棒的网站 cron-expression-generator 帮助我们通过 UI
获取 crontab 表达式