在现代应用程序开发中,定时任务是不可或缺的组成部分。无论是数据同步、邮件发送、系统维护,还是定期生成报告,都需要可靠的定时任务支持。本文将介绍如何使用 Cronos,一个强大的 .NET 任务调度库,通过控制台应用程序来实现定时任务。
Cronos 是一个轻量级的 .NET 库,用于解析和计算 CRON 表达式。它允许开发者使用熟悉的 CRON 语法来安排任务的执行时间。Cronos 的主要特点包括:
在开始之前,请确保您已安装以下环境:
在项目中安装 Cronos 包:
Bashdotnet add package Cronos
接下来,我们将创建一个通用的定时任务基类,使用 Cronos
来解析 CRON 表达式,并使用 Task.Delay
来等待下一个执行时间。
C#using Cronos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppCron
{
public abstract class CronJob
{
private readonly CronExpression _expression;
private readonly TimeZoneInfo _timeZoneInfo;
protected CronJob(string cronExpression, TimeZoneInfo timeZoneInfo = null)
{
_expression = CronExpression.Parse(cronExpression, CronFormat.IncludeSeconds); // 指定格式为包含秒
_timeZoneInfo = timeZoneInfo ?? TimeZoneInfo.Local;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var next = _expression.GetNextOccurrence(DateTimeOffset.Now, _timeZoneInfo);
if (next.HasValue)
{
var delay = next.Value - DateTimeOffset.Now;
if (delay.TotalMilliseconds > 0)
{
await Task.Delay(delay, cancellationToken);
}
if (!cancellationToken.IsCancellationRequested)
{
await ExecuteAsync(cancellationToken);
}
}
else
{
break;
}
}
}
protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
}
}
让我们创建一个示例任务,每分钟打印一条消息。
C#using System;
using System.Threading;
using System.Threading.Tasks;
public class PrintMessageJob : CronJob
{
public PrintMessageJob() : base("0 * * * * *") // 每分钟的第 0 秒执行
{
}
protected override Task ExecuteAsync(CancellationToken cancellationToken)
{
Console.WriteLine($"当前时间:{DateTime.Now}");
return Task.CompletedTask;
}
}
修改 Program.cs
文件:
C#using System;
using System.Threading;
using System.Threading.Tasks;
namespace CronosDemo
{
class Program
{
static async Task Main(string[] args)
{
var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, eventArgs) =>
{
Console.WriteLine("正在退出...");
cts.Cancel();
eventArgs.Cancel = true;
};
var job = new PrintMessageJob();
await job.StartAsync(cts.Token);
}
}
}
每分钟,程序将输出当前时间。
修改任务的 CRON 表达式:
C#public class PrintMessageJob : CronJob
{
public PrintMessageJob() : base("*/5 * * * * *") // 每隔 5 秒执行
{
}
// 其余代码保持不变
}
创建一个新的任务类:
C#using System;
using System.Threading;
using System.Threading.Tasks;
public class DataBackupJob : CronJob
{
public DataBackupJob() : base("0 0 2 * * *") // 每天凌晨 2 点执行
{
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
Console.WriteLine("开始数据备份...");
// 模拟备份操作
await Task.Delay(2000, cancellationToken);
Console.WriteLine("数据备份完成!");
}
}
修改 Program.cs
,使其可以同时管理多个任务:
C#using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace CronosDemo
{
class Program
{
static async Task Main(string[] args)
{
var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, eventArgs) =>
{
Console.WriteLine("正在退出...");
cts.Cancel();
eventArgs.Cancel = true;
};
var jobs = new List<CronJob>
{
new PrintMessageJob(),
new DataBackupJob()
};
var tasks = new List<Task>();
foreach (var job in jobs)
{
tasks.Add(job.StartAsync(cts.Token));
}
await Task.WhenAll(tasks);
}
}
}
CRON 表达式由空格分隔的六个字段组成:
text┌──────── 秒 (0 - 59) │ ┌────── 分钟 (0 - 59) │ │ ┌──── 小时 (0 - 23) │ │ │ ┌── 日期 (1 - 31) │ │ │ │ ┌ 月份 (1 - 12) │ │ │ │ │ ┌─ 星期 (0 - 6) [星期日=0] │ │ │ │ │ │ * * * * * *
* * * * * *
:每秒执行0 * * * * *
:每分钟的第 0 秒执行0 0 * * * *
:每小时的第 0 分 0 秒执行0 0 2 * * *
:每天凌晨 2 点执行0 */5 * * * *
:每隔 5 分钟执行0 0 9-17 * * 1-5
:周一至周五的 9 点至 17 点,每小时执行一次Cronos 为 .NET 应用程序提供了强大的定时任务调度能力。通过本文的控制台示例,您可以轻松实现各种定时任务需求。记住要根据实际业务场景选择合适的 CRON 表达式,并始终关注任务的可靠性和性能。
希望这篇文章对您有所帮助,祝您在 .NET 开发中一切顺利!
本文作者:rick
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!