码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 定时任务还想上 Hangfire?这个被 AI Agent 项目看上的 TickerQ,把反射全干掉了


    TickerQ 踩中了 .NET 转向 AOT 和源生成的大趋势,设计在线;OpenClaw.NET 的 /loop 则把这个趋势落到了一个看得见的场景里——给 AI Agent 写定时循环这件事,用 .NET 的源生成调度器一千行左右就能落地,还全程 AOT。
    合集 - AI开源项目(61)
    1.为 openclaw.net 集成 ElBruno.MempalaceNet 记忆系统05-032.Graphify-DotNet:AI 驱动的 .NET 代码知识图谱构建工具05-023.SonnetDB:.NET 生态下的高性能嵌入式时序数据库04-284.C# 原生编码智能体运行时 SharpClawCode04-275.SharpIDE: 基于 .NET 与 Godot 引擎的跨平台开源 IDE04-266.OpenClaw.NET .NET 原生插件开发完全指南:以 Mempalace 插件为范例05-057..NET生态系统中的A2A(Agent-to-Agent)协议支持与跨平台多智能体协同05-068.Memgraph 与 Neo4j 图数据库对比及 .NET 生态适配分析05-089.OpenClaw.NET 外部 CLI 连接器 (External CLI Connectors) 详细技术总结05-1010.OpenClaw.NET:给智能以形态05-1211.架构融合:Activity Host 作为确定性编排与认知智能代理的桥梁05-1812.OpenClaw.NET 兼容性目录指南(Compatibility Catalog)05-2113.当 AgentGateway 遇上 OpenClaw.NET:企业级智能体基础设施的深度协同实战06-0614.OpenClaw.NET 上线 MetaSkills :软件工程第一性原理的工业级实践06-1715.OpenClaw.NET MetaSKILLs 系统深度解析:AI Agent 正在学会「自己给自己写技能」06-1816.OpenClaw.NET 重大更新:Goal 机制登场,让 AI Agent 不再"半途而废"06-1817.OpenClaw.NET 祭出 TokenJuice:Agent 时代的"Token 瘦身引擎",让 LLM 上下文不再膨胀06-1918.从 OpenClaw.NET 的 /loop 实现,看 Loop Engineering 如何从概念走向工程实践06-2019.将 Rust 绑定到 .NET 10:Oxigraph 的 FFI 桥接实践06-2820.Token IO 架构的设计游戏:大模型产品形态四年演进的本质06-2921.当 AI 不再只是"说话":OpenClaw.NET 率先原生支持 MCP Apps06-3022.你的 AI Agent 会在服务器上"修仙"——OpenClaw.NET 长持久会话技术解读07-0423.从 Bun 的 Rust 重写,看 C# 如何重建 AI 基础设施层07-1024.当 AI 对话里直接弹出业务界面:MCP Apps 正在改写 SaaS 的集成逻辑07-1225.MCP + A2A 融合:协议层已就绪,信任层才是硬仗07-2126.C# MCP SDK 2.0 即将发布:去会话化、去握手、去运维噩梦07-2427.数字员工的成本账:OpenClaw.NET 如何用工程化实现"成功任务的单位经济学"(下)07-2328.25家巨头联名的那封公开信,为什么数字员工架构师应该逐字读一遍07-2829.从 Harness 引擎到 MetaSkill DAG 的确定性架构07-3030.从DDD到Ontology:当数字员工不再认"限界上下文"这堵墙07-3131.把 284B 的 DeepSeek V4 Flash 装进纯 .NET:TensorSharp 用一天改写了 .NET 推理栈的位置08-0132.MCP 第五版 × OpenClaw.NET:从协议升级到生态编排08-0233.纯 C# 追平 llama.cpp?.NET 本地推理三国杀08-0334."从"前锋"到"中场":为什么 Agent 基础设施的建设者必须是系统思考者08-0435.修 Bug 的手艺与架构的艺术:从熵增到熵减08-0636.改变世界的17个方程,如何重塑 GoodCrew 的架构哲学08-0637.Agent 系统的不确定性治理:当软件工程遭遇"梯度下降"08-1138.WorkBuddy 专家团的下一步:用 MetaSkill 把「提示词约定」升级为「运行时硬约束」08-1039.JVMGuard 来了,.NET 开发者别慌:你的 dotnet-monitor 早就准备好了08-1440.两种 Harness 哲学:从 DeepSeek Harness 的"过度抽象"争议,看 OpenClaw.NET 的另一种答案08-1541.当"入门第一课"的作者开始 Vibe Coding:廖雪峰 2026 上半年 AI 编程实践深度探索08-1642.TensorSharp 最新进展研究报告:从 DeepSeek V4 Flash 到 GLM-5.2,以及等待中的 GLM-5.308-2043.AI 编程时代,.NET 的机会在哪里?08-2544.3 张卡到底能不能跑大模型推理?从 vLLM、llama.cpp 到 TensorSharp 的多卡真相08-2845.纯 .NET 手写 CUDA kernel,GLM-5.3-Flash decode 跑出 llama.cpp 的 2 倍08-2946.TensorSharp 3.3.0.0 发布,视频生成、DFlash2 投机解码、安全加固一起来了08-3147..NET 异常处理的"暗门":代码里写满 catch,你依然能抓住它——从一个 AI Agent 运行时的源码说起09-1148.MetaSkill 落地 .NET:当 Agent 从「调用工具」进化到「组织工具」09-0349.写给 Java 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Spring 思维,跑起一个生产级 AI Agent09-0650.写给 Golang 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Go 思维,跑起一个生产级 AI Agent09-0451.写给 Python 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Python 思维,跑起一个生产级 AI Agent09-0552.写给 TypeScript 工程师的 OpenClaw.NET 上手指南:用你熟悉的 TS 思维,跑起一个生产级 AI Agent09-0553.写给 Rust 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Rust 思维,跑起一个生产级 AI Agent09-0854.写给 C++ 工程师的 OpenClaw.NET 上手指南:用你熟悉的 C++ 思维,跑起一个生产级 AI Agent09-1055.写给 PHP 工程师的 OpenClaw.NET 上手指南:用你熟悉的 PHP 思维,跑起一个生产级 AI Agent09-0956.RedNb.Nacos 2.0.0 正式发布:.NET 接入 Nacos 3.2.4,AI Registry 全能力落地09-1357.把 LLM 密钥从环境变量里解放出来:OpenClaw.NET 迎来 Vault/OpenBao 密钥后端09-1658.事件风暴遇上 MetaSkill:把企业「世界模型」变成可执行的 DAG09-2159.TensorSharp 支持 Jev 模式了:一次去噪,直接读出决策09-23
    60.定时任务还想上 Hangfire?这个被 AI Agent 项目看上的 TickerQ,把反射全干掉了09-24
    61.不让模型写作文,直接从它脑子里读答案:Jev 决策在 .NET 的两条路线09-25
    收起

    写后端的人都躲不开定时任务:每天凌晨跑对账、每五分钟拉一次订单状态、给超时未支付的订单自动关单。.NET 这边的选择说多也多,说少也少——Quartz.NET 功能全但配置啰嗦,Hangfire 用着顺手,可一上 Dashboard 就开始掏钱,而且它那套基于反射的作业发现,在 Native AOT 时代多少有点格格不入。

    今天要聊的 TickerQ,走的是另一条路:编译期用 Source Generator 把所有作业注册好,运行时零反射,自带持久化和监控面板。GitHub 上 3600 多个 star,最近 .NET 圈子里讨论度不低。

    不过这篇不只是把别人介绍过的东西再抄一遍。真正让我注意到它的,是 NuGet 官方页面上一个细节:在"依赖 TickerQ 的热门仓库"榜单里,除了 ABP 这种企业级框架,还躺着 clawdotnet/openclaw.net——一个用 .NET 写的自托管 AI Agent 运行时。一个把 Native AOT 写进标语的项目,定时调度这块交给了一个"新星"库。顺着挖下去,挖到一个挺有意思的工程案例:用 TickerQ 给 AI Agent 装"定时心跳",实现 /loop 定时循环指令。
    tickerq-loop-architecture

    TickerQ 是什么

    仓库: https://github.com/Arcenox-co/TickerQ ,文档: https://tickerq.net 。

    先报数据,2026 年 9 月下旬从 GitHub API 拉的:3,600+ star,210+ fork,仓库 2023 年 4 月创建,更新很勤。License 是 MIT + Apache 2.0 双协议,商用没有障碍。版本号从 2.x 直接跳到 10.x,团队解释是为了跟 NuGet 包版本对齐,看着吓人,其实就是数字游戏。

    传统调度框架找作业的方式大同小异:启动时扫程序集,用反射找带特定 Attribute 的方法,再靠字符串配置把它们串起来。这套玩法有两个毛病:启动慢、有开销是一方面;更要命的是方法名、cron 表达式全写在字符串里,写错了到运行时才炸。而且反射和 AOT 裁剪天生犯冲,.NET 8 之后想把服务发布成 Native AOT,Hangfire 这类框架基本没戏。

    TickerQ 的做法是把这件事挪到编译期。你写一个普通的类方法,打上 [TickerFunction] 特性,Source Generator 在编译时就把方法名、类型、调度配置全部生成好。换来三个好处:启动没有反射扫描的开销;cron 写错了编译期直接报错;整个库可裁剪、可 AOT,官方首页明晃晃写着 Native AOT ready。

    核心包就一个,dotnet add package TickerQ 装完,三步走:

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddTickerQ();
    
    var app = builder.Build();
    app.UseTickerQ();
    app.Run();
    
    using TickerQ.Utilities.Base;
    
    public class MyJobs
    {
        [TickerFunction("HelloWorld")]
        public async Task HelloWorld(
            TickerFunctionContext context,
            CancellationToken cancellationToken)
        {
            Console.WriteLine($"Hello from TickerQ! Job ID: {context.Id}");
        }
    }
    

    定时跑就用 cron 特性标注:

    [TickerFunction("Cleanup", cronExpression: "0 2 * * *")]  // 每天凌晨两点
    public async Task Cleanup(TickerFunctionContext ctx, CancellationToken ct)
    {
        // 清理过期数据...
    }
    

    想临时插个一次性任务,注入 ITimeTickerManager,AddAsync 一调就完事。

    几个我在意的设计:

    持久化用你自己的库,不另起炉灶。EF Core Provider 支持 PostgreSQL、SQL Server、SQLite、MySQL,不想引 EF 还有 Redis Provider。作业状态就躺在你自己的基础设施里,备份、迁移都顺手。

    Dashboard 不收钱。基于 SignalR 的实时面板,执行状态、失败记录、重试情况都看得见,还能直接在面板上启用/禁用某个 cron 作业,不用改代码不用重新发布。这个功能在生产环境是真的救命。

    多节点也做了。加实例,靠 Redis 心跳做分布式协调,节点挂了有 dead-node 清理,锁机制保证同一个作业不会被两个节点同时抢走。

    OpenClaw.NET 又是什么

    https://github.com/clawdotnet/openclaw.net ,一个自托管的 AI Agent 运行时。跑一个本地网关,连托管或本地模型(OpenAI、Claude、Gemini、DeepSeek、Ollama 都有),给 Agent 配 80 多个工具面和记忆,再通过桌面端(Avalonia 写的 AgentQi Companion)、浏览器、CLI、TG、WhatsApp 这些渠道对话。

    它的工程取向很明确:Native AOT 优先,启动快,内存低,零反射。发行包直接附带 AOT 编译好的网关和 CLI,解压就能跑。

    这就是理解它选型 TickerQ 的钥匙。一个把 Native AOT 当命根子的系统,挑调度框架时,第一眼就会把所有反射重、裁剪不友好的老面孔筛掉。

    用 TickerQ 给 AI Agent 装"定时心跳"

    OpenClaw.NET 最近合并的 /loop 命令(PR #156,社区贡献者 geffzhang 提交,思路来自 OpenAI Codex 的 /loop 原语),是个不错的 TickerQ 实战样本:1,033 行代码,11 个文件,62 个测试。

    功能不复杂:聊天界面输入 /loop 5m check CI status,系统每 5 分钟往会话里注一次系统消息,驱动 Agent 持续检查 CI 状态并汇报,直到任务完成自动终止。拆开来,里面有几个地方做得挺讲究。

    混合调度。 这是整个实现的地基。TickerQ 当前的版本有个特点:cron 表达式只支持编译期声明,不暴露"运行时再动态建一个每 5 分钟跑的任务"这种接口。你只能写死 [TickerFunction("AgentLoopExecutor", "* * * * *")],编译完就定了。但 /loop 显然要动态调度——用户随时发起新循环,间隔还各不相同。

    PR 的做法是:编译期挂一个每分钟 tick 一次的 TickerQ 定时器当"心跳",运行时维护一张 ConcurrentDictionary 内存注册表,记每个活跃 loop 的下次触发时间和间隔。心跳一到,扫一遍注册表,把到期的推进一轮。

    没魔改 TickerQ,也没引入第二个调度依赖,ConcurrentDictionary 的线程安全性久经验证。代价是多了一层内存轮询,但对分钟级精度完全够用。这条经验对 TickerQ 用户挺值钱:框架不给动态 cron,不代表做不了动态调度,一个高频心跳加一张注册表,就把"编译期调度器"和"运行时动态任务"缝在了一起。

    零入侵 AgentRuntime。 Loop 的提示词不是直接塞给模型,而是通过 MessagePipeline.InboundWriter 以 ChannelId="cron" 的系统消息注入。这条消息走和正常用户消息完全相同的投递管道,由已有的 GatewayInboundMessageWorker 消费、转发。AgentRuntime 一行代码没改——MafAgentRuntime 也一样。

    这里补一句背景:OpenClaw.NET 是双运行时结构。除了内置的 AgentRuntime,还有一个基于 Microsoft Agent Framework 的 MafAgentRuntime,两个运行时实现同一套入站消息接口。/loop 的消息走的是管道,不碰任何一个运行时的内部实现,所以对两个运行时等效生效。整个 PR 里我最喜欢的就是这个决定。

    双层终止。 这块做得有点 paranoid,但事出有因。OpenAI Codex 早期曾因缺乏有效终止机制,Agent 干完活继续空转,日志膨胀到 34GB/天。所以 PR 用了两层兜底:主路径是模型主动调 loop_control(status="complete") 工具,显式声明干完了;备用路径是检测响应文本里的终止关键词(LOOP_TERMINATE、DONE、WORK_COMPLETE 之类),用 FrozenSet 存,O(1) 查找。只有被无限循环整过的人,才会在终止条件上这么较真。

    零反射。 整个实现零反射、零动态代码生成:[GeneratedRegex] 编译期生成正则,[TickerFunction] 源生成器处理调度声明,System.Text.Json 源生成器序列化 payload,关键词集合用 FrozenSet 冻结。Native AOT 会把反射和动态代码裁掉,轻则性能掉,重则直接起不来。TickerQ 的零反射在这里不是性能卖点,是整套方案能编进 AOT 二进制的前提。

    调度之外还有一张精简的三态机:Scheduled → Running → Terminated(终态)。配套三条规则:同一个 session 只能有一个活跃 loop,重复发起直接覆盖旧的;上一轮没跑完时新消息排队等,不强行中断;语义终止后不弹通知,安静退出,把界面还给用户。最后这条我觉得是细节见功力——没人愿意被一个已经没必要的循环反复弹窗。

    /loop 还跟 OpenClaw.NET 里另一个原语 /goal 形成互补:/goal 是模型一停就自动续跑,适合"修完全部测试"这种一口气推进的;/loop 是定时巡检,适合"每 5 分钟看一眼 CI"这种等外部状态变化的。同一个 session 可以同时挂俩,一个巡检,一个推进。

    为什么这对 TickerQ 算个背书

    一个把 Native AOT 当命根子的系统,把定时调度的地基交给 TickerQ,逻辑很清楚:零反射加源生成,能编进 AOT 二进制,这是硬门槛;cron 编译期校验,心跳表达式写错构建直接失败;核心包零外部依赖,符合运行时"克制"的切分哲学;Dashboard 和持久化按需引入,用多少引多少。

    ABP 用 TickerQ,证明它能在企业级框架里站住脚。OpenClaw.NET 这个案例证明的是另一件事:在 AOT、源生成这条新技术路线上,它是目前 .NET 里比较顺手的调度原语。

    这个案例顺带说明的事

    今年 AI 圈概念迭代快得应接不暇:Prompt Engineering 还没消化,Context Engineering 登场;Harness Engineering 刚存进收藏夹,Loop Engineering 又来了。判断新概念是不是噱头,最好别争论定义,去看真实的工程实现。

    /loop 的本质可以压成一句话:Loop = Cron(定时触发)+ 决策器(判断下一步干什么)。Claude Code 的负责人今年说过一句类似"我不再 prompt Claude 了,我写 loop 让它们运行"的话。人的活计正在从"跟模型对话"变成"设计模型的运行规则"。而"定时触发"这一半,TickerQ 这类现代调度器已经把路铺好了。

    想动手的话,建议先问自己五个问题:触发条件清楚吗?上下文可信吗?工具边界受控吗?结果可验证吗?停止条件明确吗?都有答案再写 loop,缺一个,就是把混乱自动化。

    泼点冷水

    说点缺点,免得你以为我在恰饭。

    第一,TickerQ 还年轻。3600 star 在 .NET 生态里只能算新星,对比 Hangfire 十几年生产验证,坑肯定没踩完。GitHub 上挂着 100 多个 open issue,用之前先搜一下自己的场景是不是已知问题。

    第二,文档还在追赶代码。部分高级用法得翻源码示例确认,不如老牌框架厚实。

    第三,/loop 的动态调度是靠内存注册表实现的——进程一重启,活跃 loop 就没了。对"每 5 分钟看 CI"这种可重建的循环无所谓,但如果你要做重启后必须恢复的动态任务,得自己接 EF Core 持久化做恢复逻辑,动手前先评估清楚。

    第四,场景简单就别上框架。一个后台服务里跑个 PeriodicTimer 就够的活,别为这个引库。杀鸡别用牛刀。

    适合谁:被 Hangfire 配置或收费困扰的团队;要上 Native AOT 的项目;需要免费监控面板和多节点协调的中小型系统;还有正在做 AI Agent、需要给 Agent 装"定时心跳"的人。不适合谁:极度求稳、非十年老库不用的团队;只有两三个定时任务的玩具项目。

    结语

    折腾下来的感觉是:TickerQ 踩中了 .NET 转向 AOT 和源生成的大趋势,设计在线;OpenClaw.NET 的 /loop 则把这个趋势落到了一个看得见的场景里——给 AI Agent 写定时循环这件事,用 .NET 的源生成调度器一千行左右就能落地,还全程 AOT。

    当不了 Hangfire 的平替,但完全可以进"下一个项目默认选它"的候选名单。哪天你的 Agent 需要一颗定时心脏,说不定会想起这个组合。

    参考链接:

    1. TickerQ 仓库:https://github.com/Arcenox-co/TickerQ
    2. TickerQ 官方文档:https://tickerq.net
    3. OpenClaw.NET 仓库:https://github.com/clawdotnet/openclaw.net
    4. OpenClaw.NET PR #156(/loop 实现):https://github.com/clawdotnet/openclaw.net/pull/156

    欢迎大家扫描下面二维码成为我的客户,扶你上云

  • 相关阅读:
    Python网络爬虫4-实战爬取pdf
    多壁碳纳米管-室温离子液体1-丁基-3-甲基咪唑六氟磷酸盐([EMIM]PF6)修饰辣根过氧化物酶(HRP)|新型碳糊酶电极(HRP-MWCNTs-CILE)
    React create-react-app 里配置代理(解决跨域)
    laspy读写点云文件,附las文件支持格式
    Mathematica for Linux v13.1.0 科学计算软件多语言版
    基于JavaWeb的家庭食谱管理系统设计与实现
    前后端接口设计与配置中心系统<二十九>-------HiAbility SDK开发4【支付能力集成】
    键盘切换不出中文输入法的解决方法
    理解Nginx反向代理详解
    CentOS 7 搭建 LVS集群 DR模式
  • 原文地址:https://www.cnblogs.com/shanyou/p/23104373
  • 最新文章
  • 【FHE】我们如何实现同态加密推理(八):SiLU 的密文化——两条路径,和一个 8 字节的开关
    SQLcl 中 c/old/new 替换变量为何失效?先定位再替换
    不让模型写作文,直接从它脑子里读答案:Jev 决策在 .NET 的两条路线
    Halo插件:支持GitHub的图床附件策略
    电视投屏界的“一股清流”!SimpleTVCast 6.0.0-beta 抢先体验:无需TV端App,界面大换血!✨
    华三VXLAN集中式网关实战指南:Spine多活网关 + 双活接入(M-LAG)
    软件更好写之后口碑会更重要
    大 O、大 Omega、大 Theta 的区别,O(n) 复杂度是什么意思
    Java标签跳转:一个鲜为人知但却很实用的小技巧
    多智能体系统论文速读
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号