#3341·quartznet

Trim 和 AOT 兼容性追踪 — 还剩下什么

作者: lahma创建于 2026年8月22日更新于 2026年9月3日

本问题开启的八个步骤已经完成。Quartz设置了IsTrimmable,IsAotCompatible以及裁剪、AOT 和单文件分析器,并将TreatWarningsAsErrors设置为true;ObjectUtils已删除,火路将[DynamicallyAccessedMembers]一路传递;HTTP 线程合约、存储的 JSON 片段和Quartz配置部分均由源代码生成;Quartz.Trimming.Canary原生发布并运行在 Windows、Linux 和 macOS 上的每个 Pull Request 中,通过真实的 SQLite 存储进行调度和触发,并通过 IConfiguration 绑定整个调度器。Quartz 不会产生任何 IL3050Quartz.Jobs,Quartz.Plugins,Quartz.HttpClient,Quartz.AspNetCore,Quartz.Extensions.RedisQuartz.Plugins.TimeZoneConverter被标记为可裁剪,并带有自己的基线;Quartz.Serialization.NewtonsoftQuartz.Dashboard则相反,故意这样做。剩下的就是23 个记录的 IL2xxx 条目,分布在 14 种类型中,它们分别位于 src/Quartz/TrimAnalysisBaseline.cs(18 个,分布在 11 种类型中)、“src/Quartz/ILLink.Suppressions.xml”(另一个条目,只有 ILLink 可以看到),以及四个包基线。它们有三种形状,其中没有一个是错误:

  1. 一个字符串命名一个类型 — 平面 quartz.* 关键字、JOB_CLASS_NAME、驱动名称、插件或监听器类型名称、quartz_jobs.json 中命名的作业。每个 公共 API,接受此类字符串 都已经标记为 [RequiresUnreferencedCode]。记录的内容是 Quartz 读取自己的配置和自己的表,这些路径可以从 AddQuartz 访问,或者通过 Quartz 不拥有的接口访问。
  2. 一个值转换为编译器无法看到的属性Quartz.Util.ValueConverter。目标值以 PropertyInfo.PropertyType 形式出现,框架没有标注此类信息,也无法标注,因此无法构建链条。
  3. 鸭式提供程序错误TransientErrorDetector 从 Quartz 刻意不引用的类型中读取 SqlException.NumberSqliteException.SqliteErrorCode

内容来源: quartznet/quartznet