c# - 在 ASP.NET Core 3.1 中,如何在未来的特定日期和时间安排具有托管服务的后台任务(Cron 作业)?
问题描述
我正在开发一个基于 ASP.NET Core 3.1 的项目,我想向它添加一个特定的功能,以安排将来在帖子作者指定的日期和时间发布帖子(类似于 Wordpress 通过它的 cron 工作)。例如,如果我们从用户那里收到这个日期和时间:
2020-09-07 14:08:07
那么,如何通过使用托管服务只运行一次并更改数据库中的标志并在此之后保存更改来为其安排后台任务?
我读过一些关于它的文章,但他们没有指定日期和时间,只是提到了每 5 秒重复的任务以及类似 cron 表达式的东西,但是,我需要知道的是如何安排后台任务特定日期和时间?
先感谢您。
解决方案
我将 CrontabSchedule 与 IHostedService 结合起来。下面的实现是轻量级的(没有架构强加库)并且没有轮询。
public class SomeScheduledService: IHostedService
{
private readonly CrontabSchedule _crontabSchedule;
private DateTime _nextRun;
private const string Schedule = "0 0 1 * * *"; // run day at 1 am
private readonly SomeTask _task;
public SomeScheduledService(SomeTask task)
{
_task = Task;
_crontabSchedule = CrontabSchedule.Parse(Schedule, new CrontabSchedule.ParseOptions{IncludingSeconds = true});
_nextRun = _crontabSchedule.GetNextOccurrence(DateTime.Now);
}
public Task StartAsync(CancellationToken cancellationToken)
{
Task.Run(async () =>
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(UntilNextExecution(), cancellationToken); // wait until next time
await _task.Execute(); //execute some task
_nextRun = _crontabSchedule.GetNextOccurrence(DateTime.Now);
}
}, cancellationToken);
return Task.CompletedTask;
}
private int UntilNextExecution() => Math.Max(0, (int)_nextRun.Subtract(DateTime.Now).TotalMilliseconds);
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
推荐阅读
- javascript - 我如何从数组中删除或替换一个值
- uwebsockets - 如何在 uWebSockets.js 中获取套接字路径?
- php - 无法从 php 连接到数据库,远程服务器错误。提供的刷新令牌已过期
- android - ContactsContract.CommonDataKinds.Event.START_DATE 包括联系电话号码
- javascript - 我无法将不同的模态窗口与不同的对象相关联
- userform - 我有一个准备就绪的用户表单,但是当我尝试将其添加为加载项时,它不起作用。请帮忙!显示的错误是下标超出范围
- http - 为什么不推荐使用 HAL(超文本应用程序语言)并且不广泛使用?
- python-3.x - 如何去除图像的背景
- python-3.7 - 我有 python 3.9,我想用 python 3.7 创建虚拟环境
- java - 如何添加手指移动 Java 画布