{"id":19990086,"url":"https://github.com/2881099/FreeScheduler","last_synced_at":"2025-05-04T09:34:24.773Z","repository":{"id":49829900,"uuid":"518300955","full_name":"2881099/FreeScheduler","owner":"2881099","description":"轻量化定时任务调度，支持集群、临时的延时任务和重复循环任务(可持久化)，可按秒，每天/每周/每月固定时间，自定义间隔执行，支持 .NET Core 2.1+、.NET Framework 4.0+ 运行环境。","archived":false,"fork":false,"pushed_at":"2024-03-26T12:02:45.000Z","size":4144,"stargazers_count":272,"open_issues_count":20,"forks_count":41,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-05-15T21:26:12.616Z","etag":null,"topics":["fluentscheduler","freescheduler","hashedwheeltimer","quartz"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/2881099.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-27T03:52:31.000Z","updated_at":"2024-05-11T03:48:53.000Z","dependencies_parsed_at":"2023-12-13T12:40:25.098Z","dependency_job_id":"b21148dc-6806-42b5-a4ce-eeef4717b57c","html_url":"https://github.com/2881099/FreeScheduler","commit_stats":{"total_commits":39,"total_committers":2,"mean_commits":19.5,"dds":0.07692307692307687,"last_synced_commit":"e71a78871bdcdb04dadacbea66ca1a6ee44b4375"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2881099%2FFreeScheduler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2881099%2FFreeScheduler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2881099%2FFreeScheduler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2881099%2FFreeScheduler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/2881099","download_url":"https://codeload.github.com/2881099/FreeScheduler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224391390,"owners_count":17303609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fluentscheduler","freescheduler","hashedwheeltimer","quartz"],"created_at":"2024-11-13T04:50:58.151Z","updated_at":"2024-11-13T04:51:10.855Z","avatar_url":"https://github.com/2881099.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"FreeScheduler 是利用 IdleBus 实现的轻量化定时任务调度，支持集群、临时的延时任务和重复循环任务(可持久化)，可按秒，每天/每周/每月固定时间，自定义间隔执行，支持 .NET Core 2.1+、.NET Framework 4.0+ 运行环境。\n\n\u003e IdleScheduler 已正式改名为 FreeScheduler\n\n如果对本项目感兴趣，欢迎加入 FreeSql QQ讨论群：8578575\n\n## Quick start\n\n\u003e dotnet add package FreeScheduler\n\n\u003e Install-Package FreeScheduler\n\n```csharp\nstatic Scheduler scheduler = new FreeSchedulerBuilder()\n    .OnExecuting(task =\u003e\n    {\n        Console.WriteLine($\"[{DateTime.Now.ToString(\"HH:mm:ss.fff\")}] {task.Topic} 被执行\");\n        switch (task.Topic)\n        {\n            case \"武林大会\": Wulin(task.Body); break;\n            case \"攻城活动\": AttackCity(task.Body); break;\n        }\n    })\n    .Build();\n```\n\n| Method | 说明 |\n| -- | -- |\n| OnExecuting(Action\\\u003cTaskInfo\\\u003e executing) | 任务触发 |\n| UseTimeZone() | 设置时区 |\n| UseStorage() | 基于 数据库或者 Redis 持久化 |\n| UseCluster() | 开启集群（依赖 Redis），支持跨进程互通 |\n| UseCustomInterval() | 自定义间隔（可实现 cron） |\n| UseScanInterval() | 扫描间隔（默认200ms），值越小触发精准 |\n| Build() | 创建 Scheduler 对象 |\n\n使用 ASP.NET Core 项目，一行代码解决如下：\n\n```csharp\napp.UseFreeSchedulerUI(\"/freescheduler/\");\n```\n\n![image](https://github.com/2881099/FreeSql.Wiki.VuePress/assets/16286519/a5d5f4bb-6af9-4695-9570-8777c39d7329)\n\n## 集群特性\n\n- 支持 单项目，多站点部署\n- 支持 多进程，不重复执行\n- 支持 进程退出后，由其他进程重新加载任务（约30秒后）\n- 支持 进程互通，任意进程都可以执行（RemoveTask/ExistsTask/PauseTask/RunNowTask/RemoveTempTask/ExistsTempTask）\n- 支持 进程意外离线后，卸载进程内的任务，重新安排上线\n\n1、临时任务(不可持久化)\n\n```csharp\nvoid Callback()\n{\n    Console.WriteLine(\"时间到了\");\n    scheduler.AddTempTask(TimeSpan.FromSeconds(10), Callback); //下一次定时\n}\nscheduler.AddTempTask(TimeSpan.FromSeconds(10), Callback);\n```\n\n| Method | 说明 |\n| -- | -- |\n| string AddTempTask(TimeSpan, Action) | 创建临时的延时任务，返回 id |\n| bool RemoveTempTask(string id) | 删除任务(临时任务) |\n| bool ExistsTempTask(string id) | 判断任务是否存在(临时任务) |\n| int QuantityTempTask | 任务数量(临时任务) |\n\n2、循环任务/可持久化\n\n```csharp\n//每5秒触发，执行N次\nvar id = scheduler.AddTask(\"topic1\", \"body1\", round: -1, 5);\n\n//每次 不同的间隔秒数触发，执行6次\nvar id = scheduler.AddTask(\"topic1\", \"body1\", new [] { 5, 5, 10, 10, 60, 60 });\n\n//每天 20:00:00 触发，执行N次（注意设置时区 UseTimeZone）\nvar id = scheduler.AddTaskRunOnDay(\"topic1\", \"body1\", round: -1, \"20:00:00\");\n\n//每周一 20:00:00 触发，执行1次\nvar id = scheduler.AddTaskRunOnWeek(\"topic1\", \"body1\", round: 1, \"1:20:00:00\");\n\n//每月1日 20:00:00 触发，执行12次\nvar id = scheduler.AddTaskRunOnMonth(\"topic1\", \"body1\", round: 12, \"1:20:00:00\");\n//每月最后一日 20:00:00 触发，执行12次\nvar id = scheduler.AddTaskRunOnMonth(\"topic1\", \"body1\", round: 12, \"-1:20:00:00\");\n\n//自定义间隔 cron\nvar id = scheduler.AddTaskCustom(\"topic1\", \"body1\", \"0/1 * * * * ? \");\nnew FreeSchedulerBuilder()\n    ...\n    .UseCustomInterval(task =\u003e\n    {\n        //利用 cron 功能库解析 task.IntervalArgument 得到下一次执行时间\n        //与当前时间相减，得到 TimeSpan，若返回 null 则任务完成\n        return TimeSpan.FromSeconds(5);\n    })\n    .Build();\n```\n\n| Method | 说明 |\n| -- | -- |\n| void ctor(ITaskHandler) | 指定任务调度器（单例） |\n| string AddTask(string topic, string body, int round, int seconds) | 创建循环定时任务，返回 id |\n| string AddTask(string topic, string body, int[] seconds) | 创建每轮间隔不同的定时任务，返回 id |\n| string AddTaskRunOnDay(..) | 创建每日循环任务，返回 id |\n| string AddTaskRunOnWeek(..) | 创建每周循环任务，返回 id |\n| string AddTaskRunOnMonth(..) | 创建每月循环任务，返回 id |\n| string AddTaskCustom(string topic, string body, string expression) | 创建自定义任务，返回 id |\n| bool RemoveTask(string id) | 删除任务 |\n| bool ExistsTask(string id) | 判断任务是否存在 |\n| bool ResumeTask(string id) | 恢复已暂停的任务 |\n| bool PauseTask(string id) | 暂停正在运行的任务 |\n| bool RunNowTask(string id) | 立刻运行任务（人工触发） |\n| TaskInfo[] FindTask(lambda) | 查询正在运行中的任务 |\n| int QuantityTask | 任务数量 |\n\n3、预留任务\n\n\u003e [系统预留]清理任务数据\n\n```csharp\n//每小时触发，定期清理24小时之前的数据（单位：秒）\nscheduler.AddTask(\"[系统预留]清理任务数据\", \"86400\", round: -1, 3600);\n```\n\n4、管理任务\n\n```csharp\n// 使用 FreeSql 或者 SQL 查询 TaskInfo、TaskLog 两个表进行分页显示\nfsql.Select\u003cTaskInfo\u003e().Count(out var total).Page(pageNumber, 30).ToList();\nfsql.Select\u003cTaskLog\u003e().Count(out var total).Page(pageNumber, 30).ToList();\n\n//暂停任务\nscheduler.PauseTask(id);\n//恢复暂停的任务\nscheduler.ResumeTask(id);\n//删除任务\nscheduler.RemoveTask(id);\n//立刻运行任务（人工触发）\nscheduler.RunNowTask(id);\n```\n\n如果正在使用 ASP.NET Core 项目，一行代码解决如下：\n\n```csharp\napp.UseFreeSchedulerUI(\"/freescheduler/\");\n```\n\nhttps://github.com/2881099/FreeScheduler/tree/master/Examples/Examples_FreeScheduler_Net60\n![image](https://github.com/2881099/FreeSql.Wiki.VuePress/assets/16286519/a5d5f4bb-6af9-4695-9570-8777c39d7329)\n\n## Performance\n\n| FreeScheduler | Quartz.net | FluentScheduler | HashedWheelTimer |\n| -- | -- | -- | -- |\n| (500,000 Tasks + 10s) | (500,000 Tasks + 10s) | (500,000 Tasks + 10s) | (500,000 Tasks + 10s) |\n| \u003cimg src=\"https://github.com/2881099/FreeScheduler/blob/master/Examples/Examples_FreeScheduler_VsQuartz/performance_self.png?raw=true\"/\u003e | \u003cimg src=\"https://github.com/2881099/FreeScheduler/blob/master/Examples/Examples_FreeScheduler_VsQuartz/performance_quartz.png?raw=true\"/\u003e | \u003cimg src=\"https://github.com/2881099/FreeScheduler/blob/master/Examples/Examples_FreeScheduler_VsQuartz/performance_fluentscheduler.png?raw=true\"/\u003e | \u003cimg src=\"https://github.com/2881099/FreeScheduler/blob/master/Examples/Examples_FreeScheduler_VsQuartz/performance_hashedwheeltimer.png?raw=true\"/\u003e |\n| 383M | 1700+M | StackOverflow | 213M |\n| 70563.6066ms | 50692.5365ms | 未知 | 33697.8758ms |\n\nFluentScheduler 单个 Registry 测试正常，但目测单线程执行(间隔1-10ms)，处理速度不理想 [View Code](https://github.com/2881099/FreeScheduler/blob/master/Examples/Examples_FreeScheduler_VsQuartz/Program.cs)\n\n我尝试把 FreeScheduler 内核改成 HashedWheelTimer 内存占用更高(600兆)，结论：FreeScheduler 功能需要占用更多资源\n\n## 💕 Donation (捐赠)\n\n\u003e 感谢你的打赏\n\n- [Alipay](https://www.cnblogs.com/FreeSql/gallery/image/338860.html)\n\n- [WeChat](https://www.cnblogs.com/FreeSql/gallery/image/338859.html)\n\n## 🗄 License (许可证)\n\n[MIT](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2881099%2FFreeScheduler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F2881099%2FFreeScheduler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2881099%2FFreeScheduler/lists"}