在现代应用程序开发中,定时任务是不可或缺的组成部分。无论是数据同步、邮件发送、系统维护,还是定期生成报告,都需要可靠的定时任务支持。本文将介绍如何使用 Cronos,一个强大的 .NET 任务调度库,通过控制台应用程序来实现定时任务。
什么是 Cronos? Cronos 是一个轻量级的 .NET 库,用于解析和计算 CRON 表达式。它允许开发者使用熟悉的 CRON 语法来安排任务的执行时间。Cronos 的主要特点包括:
环境准备 在开始之前,请确保您已安装以下环境:
安装 Cronos 包 在项目中安装 Cronos 包:
dotnet add package Cronos实现定时任务 接下来,我们将创建一个通用的定时任务基类,使用 Cronos 来解析 CRON 表达式,并使用 Task.Delay 来等待下一个执行时间。
创建基础定时任务类 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)  ;     } }示例任务:打印消息 让我们创建一个示例任务,每分钟打印一条消息。
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 文件:
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);         }     } }
每分钟,程序将输出当前时间。
更多示例 示例 1:每隔 5 秒执行任务 修改任务的 CRON 表达式:
public  class  PrintMessageJob  :  CronJob {     public  PrintMessageJob ()  : base ("*/5 * * * * *" )  // 每隔 5 秒执行       {     }     // 其余代码保持不变  }
示例 2:每天凌晨 2 点执行数据备份 创建一个新的任务类:
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,使其可以同时管理多个任务:
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 表达式 CRON 表达式由空格分隔的六个字段组成:
┌──────── 秒 (0 - 59) │ ┌────── 分钟 (0 - 59) │ │ ┌──── 小时 (0 - 23) │ │ │ ┌── 日期 (1 - 31) │ │ │ │ ┌ 月份 (1 - 12) │ │ │ │ │ ┌─ 星期 (0 - 6) [星期日=0] │ │ │ │ │ │ * * * * * *常用示例 注意事项和最佳实践 时区设置 :确保任务的执行时间与预期的时区一致。默认情况下,Cronos 使用本地时区。
异常处理 :在任务执行过程中,要捕获并处理可能的异常,防止任务崩溃。
任务间隔 :避免使用过短的间隔(如每秒执行),以免对系统造成压力。
资源释放 :如果任务使用了文件、网络连接等资源,确保在任务完成后正确释放。
小结 Cronos 为 .NET 应用程序提供了强大的定时任务调度能力。通过本文的控制台示例,您可以轻松实现各种定时任务需求。记住要根据实际业务场景选择合适的 CRON 表达式,并始终关注任务的可靠性和性能。 
 该文章在 2024/12/25 10:15:10 编辑过