System.Threading.Timer最适合作为后台长任务的轻量轮询方案,因其单线程回调避免线程池耗尽,而System.Timers.Timer适合秒/分钟级简单任务但需防并发;Quartz.NET适用于复杂调度需求但配置复杂。用 System.Timers.Timer 做简单轮询,但别指望它精准它适合每秒/每分钟级的轻量任务,比如心跳上报、缓存刷新。底层靠线程池回调,不保证准时------如果 Elapsed 事件处理太慢,下一次触发会被延迟甚至丢弃。必须手动调用 Start(),构造完默认是停着的AutoReset 设为 false 才能只执行一次;设为 true(默认)才循环,但要注意避免重复触发:多个 Elapsed 可能并发执行,得自己加锁或用 Interlocked别在回调里直接 Stop() + Start() 重置间隔,会引发竞态;改用 Change() 方法(System.Threading.Timer 才有,System.Timers.Timer 没这接口)应用退出前记得调用 Dispose(),否则可能阻止进程结束用 Quartz.NET 做生产级调度,但别一上来就配集群它解决的是"每月最后一个周五上午9点发邮件"这类复杂表达式,也支持持久化、故障恢复和分布式协调。但本地开发时,RAMJobStore 就够用,硬上 AdoJobStore 反而多出数据库连接、表初始化、连接泄漏等坑。触发器表达式写错常见于少写空格,比如 "0 0 9 ? * FRI" 合法,"0 0 9?*FRI" 直接抛 ParseExceptionJob 类必须有无参构造函数,且不能是内部类(反射实例化失败)如果用 async 方法,别直接 await 在 Execute() 里------Quartz 默认同步调用,要封装成 Task.Run(() => { ... }) 或改用 IJobFactory 注入异步上下文日志里出现 "Trigger 'xxx' is set to fire now, but scheduler is in standby mode"?说明调用了 Standby() 没 Start()为什么 System.Threading.Timer 比 System.Timers.Timer 更适合后台长任务前者回调只用一个线程(可指定 ThreadPool 或 Null),后者每次 Elapsed 都可能从线程池拿新线程,容易打满池子。尤其当任务偶尔卡住,前者最多阻塞下一次,后者可能堆积一堆等待线程。 Cleanup.pictures 智能移除图片中的物体、文本、污迹、人物或任何不想要的东西
相关推荐
csdn_aspnet18 分钟前
Redis 入门:Windows、Mac安装指南青少儿编程课堂1 小时前
蓝桥杯青少组图形化省考报名倒计时·全国青少年信息素养大赛·电子学会图形化考级:校园黑白棋人机对战解析山甫aa1 小时前
锁一篇搞定:乐观锁、悲观锁、CAS、数据库锁与分布式锁【从零开始的 Web 后端学习】tellmewhoisi1 小时前
nlp:知识库检索和dify知识库创建2601_968793141 小时前
Python Requests 轻量自动化:无需浏览器,实现真人级账号浏览模拟段一凡-华北理工大学11 小时前
工业智能体:从Codex/Claude到项目实战~系列文章05:从“AI助手“到“工业智能体“:能力跃迁与落地范式深蓝AI11 小时前
ContextVar 到线程池就丢了?asyncio.to_thread 和 run_in_executor 实测岁月宁静12 小时前
什么是 Agent:从"会聊天"到"会做事"Nturmoils12 小时前
集中式与分布式怎么选:从订单读写看 KingbaseES 的架构边界岁月宁静12 小时前
AI 应用开发工程师简历怎么写:HR 初筛、技术复筛、面试追问,三道关卡各看什么?