NewLife/NewLife.RocketMQ

Add client-side pull timeout to prevent stuck consumer threads on RocketMQ 4.9.8

Co-authored-by: nnhy <506367+nnhy@users.noreply.github.com>
copilot-swe-agent[bot] authored at 2026-02-28 17:11:40 Stone committed at 2026-02-28 23:29:14
1548c7e
Tree
1 Parent(s) f25f7f8
Summary: 4 changed files with 825 additions and 1 deletions.
Modified +5 -0
Added +406 -0
Modified +8 -1
Added +406 -0
Modified +5 -0
diff --git a/ChangeLog.md b/ChangeLog.md
index e386d49..bdb4fb5 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # 更新日志
 
+## v2.7.2026.0301 (2026-03-01)
+
+### 问题修复
+- 新增`Consumer.PullTimeout`属性,默认值0表示自动取`SuspendTimeout+10_000ms`,作为客户端拉取消息的应用层超时保护,防止RocketMQ 4.9.8在SuspendTimeout后无响应导致消费线程永久阻塞
+
 ## v2.7.2026.0201 (2026-02-01)
 
 ### 依赖更新
Added +406 -0
diff --git a/NewLife.RocketMQ/.github/copilot-instructions.md b/NewLife.RocketMQ/.github/copilot-instructions.md
new file mode 100755
index 0000000..3c5b1dd
--- /dev/null
+++ b/NewLife.RocketMQ/.github/copilot-instructions.md
@@ -0,0 +1,406 @@
+# NewLife Copilot 协作指令
+
+本说明适用于新生命团队(NewLife)及其全部开源/衍生项目,规范 Copilot 及类似智能助手在 C#/.NET 项目中的协作行为。
+
+> 目标:把"每次请求必须携带的通用规则"控制在可接受体积;组件/业务专项流程放在 `.github/instructions/`,按需读取。
+
+---
+
+## 1. 核心原则
+
+| 原则 | 说明 |
+|------|------|
+| **提效** | 减少机械样板,聚焦业务/核心算法 |
+| **一致** | 风格、结构、命名、API 行为稳定 |
+| **可控** | 限制改动影响面,可审计,兼容友好 |
+| **可靠** | 先检索再生成,不虚构,不破坏现有合约 |
+| **主动** | 发现问题主动修复,不回避合理优化 |
+
+---
+
+## 2. 适用范围
+
+- 含 NewLife 组件或衍生的全部 C#/.NET 仓库
+- 不含纯前端/非 .NET/市场文案
+- 存在本文件 → 必须遵循
+
+---
+
+## 3. 组件专用指令索引(按需加载)
+
+以下专用指令**仅在相关任务时**才需要读取,避免每次请求都携带大段流程/示例。
+
+### 3.1 XCode / Cube(数据库 & Web 快速开发)
+
+当任务涉及以下任一信号时,请**先搜索并检查当前仓库** `.github/instructions/xcode.instructions.md` **是否存在**,若存在则读取并遵循:
+
+- 需求包含:XCode/Cube/魔方/实体生成/模型 XML/数据类库/数据库 CRUD/Controller 生成/`xcodetool`/`xcode` 命令
+- 解决方案/项目中出现:`NewLife.XCode` 包引用
+- 存在:`Model.xml`、`*.xcode.xml`、`*.Data.csproj`(或项目名以 `.Data` 结尾)
+- 代码出现命名空间/类型:`XCode.*`、`Entity`(XCode 实体基类)、XCode 相关特性/接口
+- **用户提到修改任意 `.xml` 文件**(如 `member.xml`、`area.xml` 等配置文件),应**主动搜索** `xcode.instructions.md` 判断是否需要引入
+
+**主动检测策略**:当用户提及 XML 文件修改时,即使未明确提到 XCode 关键字,也应先用 `file_search` 搜索 `xcode.instructions.md`,若存在则读取,以确定该 XML 文件是否属于 XCode/Cube 体系。
+
+未满足以上条件时,**不要**引入 XCode/Cube 初始化流程,避免干扰其它仓库的常规开发。
+
+---
+
+## 4. 工作流
+
+```
+需求分类 → 检索 → 评估 → 设计 → 实施 → 验证 → 说明
+```
+
+1. **需求分类**:功能/修复/性能/重构/文档
+2. **检索**:相关类型、目录、方法、已有扩展/工具(**优先复用**)
+3. **评估**:是否公共 API?是否性能热点?**是否存在潜在问题?**
+4. **设计**:列出改动点 + 兼容/降级策略
+5. **实施**:
+   - 完成用户请求的核心任务
+   - **顺带修复**发现的明显缺陷(资源泄漏、空引用、逻辑错误)
+   - **顺带优化**可简化的重复代码
+   - 保留原注释与结构,除非注释本身有误
+6. **验证**:
+   - 代码变更:必须编译通过;运行相关单元测试(未找到需说明)
+   - 仅文档变更(未修改任何代码文件):可跳过编译与单元测试
+7. **说明**:变更摘要/影响范围/风险点
+
+### 4.1 主动优化原则
+
+当用户请求分析或优化代码时,**应主动**:
+
+| 类型 | 行动 |
+|------|------|
+| **架构梳理** | 梳理代码架构并进行重构,让代码结构更清晰易懂 |
+| **语法现代化** | 使用最新的 C# 语法来简化代码,提升可读性 |
+| **缺陷修复** | 资源泄漏、空引用风险、并发问题、逻辑错误 → 直接修复,让代码更健壮 |
+| **性能优化** | 无用分配、重复计算、可池化资源 → 通过缓存减少耗时的重复计算 |
+| **代码简化** | 重复代码提取、冗余判断合并、现代语法替换 → 在不影响可读性前提下简化 |
+| **注释完善** | 补充类、接口、属性、方法头部的注释,以及方法内部重要代码的注释 |
+| **架构参考** | 参考网络上同类功能的优秀架构,给出架构调整建议 |
+
+**架构调整策略**:
+- **改动较小**:直接调整,完成后说明变更内容
+- **改动较大**:先列出调整方案,询问用户意见,待确认后再修改
+
+**不应过度保守**:
+- ❌ 仅添加注释而忽略明显的代码问题
+- ❌ 发现资源泄漏却不修复
+- ❌ 看到重复代码却不提取
+- ❌ 用户要求优化时只做表面工作
+
+**保持谨慎的场景**:
+- 公共 API 签名变更 → 需说明兼容性影响
+- 性能关键路径 → 需有依据或说明推理
+- 大范围重构 → 需先与用户确认范围
+
+### 4.2 防御性注释规则
+
+在旧有代码中,经常可以看到**被注释掉的代码**,这些注释代码前面通常带有说明文字。
+
+**这些是防御性注释**:
+- 记录了过去曾经踩过的坑
+- 目的是告诉后来人不要按照注释代码去写,否则会有问题
+- **禁止删除此类防御性注释**,用于警示后人
+
+**识别特征**:
+```csharp
+// 曾经尝试过 xxx 方案,但会导致 yyy 问题
+// var result = DoSomethingWrong();
+
+// 不要使用 xxx,否则会造成 yyy
+// await client.SendAsync(data);
+
+// 这里不能用 xxx,因为 yyy
+// stream.Flush();
+```
+
+**处理原则**:
+- ✅ 保留这类带说明的注释代码
+- ✅ 可以补充更详细的说明,解释为什么不能这样做
+- ❌ 不要删除这类防御性注释
+- ❌ 不要尝试"恢复"这些被注释的代码
+
+---
+
+## 5. 编码规范
+
+### 5.1 基础规范
+
+| 项目 | 规范 |
+|------|------|
+| 语言版本 | `<LangVersion>latest</LangVersion>`,所有目标框架均使用最新 C# 语法 |
+| 命名空间 | file-scoped namespace |
+| 类型名 | **必须**使用 .NET 正式名 `String`/`Int32`/`Boolean` 等,避免 `string`/`int`/`bool` |
+| 兼容性 | 代码需兼容 .NET 4.5+;**禁止**使用 `ArgumentNullException.ThrowIfNull`,改用 `if (value == null) throw new ArgumentNullException(nameof(value));` |
+| 单文件 | 每文件一个主要公共类型;较大平台差异使用 `partial` |
+
+### 5.2 命名规范
+
+| 成员类型 | 命名规则 | 示例 |
+|---------|---------|------|
+| 类型/公共成员 | PascalCase | `UserService`、`GetName()` |
+| 参数/局部变量 | camelCase | `userName`、`count` |
+| 私有字段(实例/静态) | `_camelCase` | `_cache`、`_instance` |
+| 属性/方法(实例/静态) | PascalCase | `Name`、`Default`、`Create()` |
+| 扩展方法类 | `xxxHelper` 或 `xxxExtensions` | `StringHelper`、`CollectionExtensions` |
+
+### 5.3 代码风格
+
+```csharp
+// ✅ 单行 if:单语句且整行不过长时同行
+if (value == null) return;
+if (key == null) throw new ArgumentNullException(nameof(key));
+
+// ✅ 单行 if:语句较长时另起一行
+if (value == null)
+    throw new ArgumentNullException(nameof(value), "Value cannot be null");
+
+// ✅ 多分支单语句:不加花括号
+if (count > 0)
+    DoSomething();
+else
+    DoOther();
+
+// ✅ 循环必须保留花括号(即使单语句)
+foreach (var item in list)
+{
+    Process(item);
+}
+```
+
+### 5.4 Region 组织结构
+
+较长的类使用 `#region` 分段组织,顺序为:`属性` → `静态`(如有)→ `构造` → `方法` → `辅助`(如有)→ `日志`。
+
+**日志 Region 规则**:
+- 类代码中如果带有 `ILog Log { get; set; }` 和 `WriteLog` 方法
+- **必须放在类代码的最后**
+- **必须用名为"日志"的 region 包裹**
+- 不要放在"辅助" region 中,应单独作为"日志" region
+
+### 5.5 现代 C# 语法
+
+优先使用最新语法(switch 表达式、模式匹配、目标类型 `new`、record 等),即使目标框架是 net45。
+
+### 5.6 集合表达式
+
+优先使用集合表达式 `[]` 初始化集合:`List<String> Tags { get; set; } = [];`
+
+### 5.7 Null 条件运算符
+
+优先使用 `?.` / `??` 简化空值检查:`span?.AppendTag("test");` `var name = user?.Profile?.Name ?? "";`
+
+---
+
+## 6. 多目标框架
+
+NewLife 支持 `net45` 到 `net10`,常用条件符号:`NETFRAMEWORK`、`NETSTANDARD2_0`、`NETCOREAPP`、`NET5_0_OR_GREATER`、`NET6_0_OR_GREATER`、`NET8_0_OR_GREATER`。
+
+新增 API 时需评估各框架兼容性,必要时提供降级实现。
+
+---
+
+## 7. 文档注释
+
+| 规则 | 说明 |
+|------|------|
+| `<summary>` | **必须同一行闭合**,简短描述方法用途 |
+| `<param>` | **必须为每个参数添加**,无论方法可见性如何 |
+| `<returns>` | 有返回值时必须添加 |
+| `<remarks>` | 复杂方法可增加详细说明(可多行) |
+| 覆盖范围 | `public`/`protected` 成员必须注释;`private`/`internal` 建议添加 |
+| `[Obsolete]` | 必须包含迁移建议 |
+
+**正确示例**:`/// <summary>获取名称</summary>` `/// <param name="id">编号</param>`
+
+**禁止**:`<summary>` 拆成多行;缺少 `<param>`;有参数但无 param 标签。
+
+---
+
+## 8. 异步与性能
+
+| 规范 | 说明 |
+|------|------|
+| 方法命名 | 异步方法后缀 `Async` |
+| ConfigureAwait | 库内部默认 `ConfigureAwait(false)` |
+| 高频路径 | 优先对象池/`ArrayPool<T>`/`Span`,避免多余分配 |
+| 反射/Linq | 仅用于非热点路径;热点使用手写循环/缓存 |
+| 池化资源 | 明确获取/归还;异常分支不遗失归还 |
+
+**内置工具优先**:`Pool.StringBuilder`、`Runtime.TickCount64`、`ToInt()`/`ToBoolean()` 等扩展方法。
+
+---
+
+## 9. 日志与追踪
+
+规则:若类包含 `ILog Log` 与 `WriteLog`,必须放在类末尾,并用名为"日志"的 `#region` 包裹;关键过程可使用 `Tracer?.NewSpan()` 埋点。
+
+---
+
+## 10. 错误处理
+
+- **精准异常类型**:`ArgumentNullException`/`InvalidOperationException` 等
+- **参数校验**:空/越界/格式
+- **TryXxx 模式**:不用异常作常规分支
+- **类型转换**:优先使用 `ToInt()`/`ToBoolean()` 等扩展方法
+- **对外异常**:不暴露内部实现/路径
+
+---
+
+## 11. 测试规范
+
+| 项目 | 规范 |
+|------|------|
+| 框架 | xUnit |
+| 命名 | `{ClassName}Tests` |
+| 描述 | `[DisplayName("中文描述意图")]` |
+| IO | 使用临时目录;端口用 0/随机 |
+| 覆盖 | 正常/边界/异常/并发(必要时) |
+
+### 测试执行策略
+
+1. 优先检索 `{ClassName}` 引用,若落入测试项目则运行
+2. 未命中则查找 `{ClassName}Tests.cs`
+3. **未发现相关测试需明确说明**,不自动创建测试项目
+
+---
+
+## 12. NuGet 发布规范
+
+| 类型 | 命名规则 | 示例 |
+|------|---------|------|
+| 正式版 | `{主版本}.{子版本}.{年}.{月日}` | `11.9.2025.0701` |
+| 测试版 | `{主版本}.{子版本}.{年}.{月日}-beta{时分}` | `11.9.2025.0701-beta0906` |
+
+- **正式版**:每月月初发布
+- **测试版**:提交代码到 GitHub 时自动发布
+
+---
+
+## 13. Markdown 文档规范
+
+| 项目 | 规范 |
+|------|------|
+| 文件编码 | **必须** UTF-8,**禁止** GB2312/GBK/UTF-8 BOM |
+| 默认存放 | 代码库根目录下的 `Doc` 目录 |
+| 文件命名 | 优先**中文文件名**,简洁描述内容 |
+
+**注意**:已有文件**必须先读取**再增量修改,**禁止直接覆盖**。
+
+---
+
+## 14. Copilot 行为守则
+
+### 必须
+
+- 简体中文回复
+- 输出前检索现有实现,**禁止重复造轮子**
+- 先列方案再实现
+- 标记不确定上下文为"需查看文件"
+- **发现明显缺陷时主动修复**(资源泄漏、空引用、逻辑错误)
+- **用户要求优化时深入分析**,不做表面工作
+
+### 鼓励
+
+- 提取重复代码为公共方法
+- 简化冗余的条件判断
+- 使用现代 C# 语法改进可读性
+- 补充缺失的资源释放逻辑
+- 修正错误或过时的注释
+
+### 禁止
+
+- 虚构 API/文件/类型
+- 伪造测试结果/性能数据
+- 擅自删除公共/受保护成员
+- 擅自删除已有代码注释(除非注释本身错误)
+- **删除防御性注释**(带说明的注释代码,记录历史踩坑经验)
+- 仅删除空白行制造"格式优化"提交
+- 删除循环体的花括号
+- 将 `<summary>` 拆成多行
+- 将 `String`/`Int32` 改为 `string`/`int`
+- 新增外部依赖(除非说明理由并给出权衡)
+- 在热点路径添加未缓存反射/复杂 Linq
+- 输出敏感凭据/内部地址
+- **发现问题却视而不见**
+- **用户要求优化时仅做注释/测试等表面工作**
+
+---
+
+## 15. 变更说明模板
+
+提交或答复需包含:
+
+```markdown
+## 概述
+做了什么 / 为什么
+
+## 影响
+- 公共 API:是/否
+- 性能影响:无/有(说明)
+
+## 兼容性
+降级策略 / 条件编译点
+
+## 风险
+潜在回归 / 性能开销
+
+## 后续
+是否补测试 / 文档
+```
+
+---
+
+## 16. 术语说明
+
+| 术语 | 定义 |
+|------|------|
+| **热点路径** | 经性能分析或高频调用栈确认的关键执行段 |
+| **基线** | 变更前的功能/性能参考数据 |
+| **顺带修复** | 在完成主任务过程中,修复发现的相关问题 |
+| **防御性注释** | 被注释掉的代码,前面带有说明,记录历史踩坑经验,用于警示后人 |
+
+---
+
+## 17. 代码优化检查清单
+
+当进行代码优化时,按以下清单逐项检查:
+
+### 架构与结构
+- [ ] 代码架构是否清晰?是否需要重构?
+- [ ] 类的职责是否单一?是否需要拆分?
+- [ ] 是否有重复代码可以提取为公共方法?
+- [ ] Region 组织是否符合规范(属性→静态→构造→方法→辅助→日志)?
+
+### 语法现代化
+- [ ] 是否可以使用更简洁的 C# 语法?(switch 表达式、模式匹配等)
+- [ ] 集合初始化是否使用了集合表达式 `[]`?
+- [ ] 是否可以使用 null 条件运算符 `?.` 简化代码?
+
+### 健壮性
+- [ ] 是否存在空引用风险?
+- [ ] 资源是否正确释放?(IDisposable、流、连接等)
+- [ ] 异常处理是否完善?
+- [ ] 并发场景是否线程安全?
+
+### 性能
+- [ ] 是否存在可以缓存的重复计算?
+- [ ] 是否有不必要的对象分配?
+- [ ] 热点路径是否避免了反射和复杂 Linq?
+- [ ] 是否使用了对象池/ArrayPool 等池化技术?
+
+### 注释与文档
+- [ ] 类、接口是否有 `<summary>` 注释?
+- [ ] 公共方法是否有完整的参数和返回值注释?
+- [ ] 方法内重要逻辑是否有注释说明?
+- [ ] 防御性注释是否保留?
+
+### 日志
+- [ ] `ILog Log` 和 `WriteLog` 是否放在类的最后?
+- [ ] 是否用名为"日志"的 region 包裹?
+
+---
+
+(完)
Modified +8 -1
diff --git a/NewLife.RocketMQ/Consumer.cs b/NewLife.RocketMQ/Consumer.cs
index 242529c..5f0252a 100644
--- a/NewLife.RocketMQ/Consumer.cs
+++ b/NewLife.RocketMQ/Consumer.cs
@@ -35,6 +35,9 @@ public class Consumer : MqBase
     /// <summary>消费挂起超时。每次拉取消息,服务端如果没有消息时的挂起时间,默认15_000ms</summary>
     public Int32 SuspendTimeout { get; set; } = 15_000;
 
+    /// <summary>客户端拉取消息超时。默认0表示自动使用SuspendTimeout加10_000ms,防止服务端超时后无响应导致消费线程永久阻塞</summary>
+    public Int32 PullTimeout { get; set; } = 0;
+
     /// <summary>拉取的批大小。默认32</summary>
     public Int32 BatchSize { get; set; } = 32;
 
@@ -702,7 +705,11 @@ public class Consumer : MqBase
             try
             {
                 var offset = st.Offset;
-                var pr = await Pull(mq, offset, BatchSize, SuspendTimeout, cancellationToken).ConfigureAwait(false);
+                // 客户端超时保护:防止服务端在SuspendTimeout后无响应导致消费线程永久阻塞
+                var pullTimeout = PullTimeout > 0 ? PullTimeout : SuspendTimeout + 10_000;
+                using var pullCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+                pullCts.CancelAfter(pullTimeout);
+                var pr = await Pull(mq, offset, BatchSize, SuspendTimeout, pullCts.Token).ConfigureAwait(false);
                 if (pr != null)
                 {
                     switch (pr.Status)
Added +406 -0
diff --git a/XUnitTestRocketMQ/.github/copilot-instructions.md b/XUnitTestRocketMQ/.github/copilot-instructions.md
new file mode 100755
index 0000000..3c5b1dd
--- /dev/null
+++ b/XUnitTestRocketMQ/.github/copilot-instructions.md
@@ -0,0 +1,406 @@
+# NewLife Copilot 协作指令
+
+本说明适用于新生命团队(NewLife)及其全部开源/衍生项目,规范 Copilot 及类似智能助手在 C#/.NET 项目中的协作行为。
+
+> 目标:把"每次请求必须携带的通用规则"控制在可接受体积;组件/业务专项流程放在 `.github/instructions/`,按需读取。
+
+---
+
+## 1. 核心原则
+
+| 原则 | 说明 |
+|------|------|
+| **提效** | 减少机械样板,聚焦业务/核心算法 |
+| **一致** | 风格、结构、命名、API 行为稳定 |
+| **可控** | 限制改动影响面,可审计,兼容友好 |
+| **可靠** | 先检索再生成,不虚构,不破坏现有合约 |
+| **主动** | 发现问题主动修复,不回避合理优化 |
+
+---
+
+## 2. 适用范围
+
+- 含 NewLife 组件或衍生的全部 C#/.NET 仓库
+- 不含纯前端/非 .NET/市场文案
+- 存在本文件 → 必须遵循
+
+---
+
+## 3. 组件专用指令索引(按需加载)
+
+以下专用指令**仅在相关任务时**才需要读取,避免每次请求都携带大段流程/示例。
+
+### 3.1 XCode / Cube(数据库 & Web 快速开发)
+
+当任务涉及以下任一信号时,请**先搜索并检查当前仓库** `.github/instructions/xcode.instructions.md` **是否存在**,若存在则读取并遵循:
+
+- 需求包含:XCode/Cube/魔方/实体生成/模型 XML/数据类库/数据库 CRUD/Controller 生成/`xcodetool`/`xcode` 命令
+- 解决方案/项目中出现:`NewLife.XCode` 包引用
+- 存在:`Model.xml`、`*.xcode.xml`、`*.Data.csproj`(或项目名以 `.Data` 结尾)
+- 代码出现命名空间/类型:`XCode.*`、`Entity`(XCode 实体基类)、XCode 相关特性/接口
+- **用户提到修改任意 `.xml` 文件**(如 `member.xml`、`area.xml` 等配置文件),应**主动搜索** `xcode.instructions.md` 判断是否需要引入
+
+**主动检测策略**:当用户提及 XML 文件修改时,即使未明确提到 XCode 关键字,也应先用 `file_search` 搜索 `xcode.instructions.md`,若存在则读取,以确定该 XML 文件是否属于 XCode/Cube 体系。
+
+未满足以上条件时,**不要**引入 XCode/Cube 初始化流程,避免干扰其它仓库的常规开发。
+
+---
+
+## 4. 工作流
+
+```
+需求分类 → 检索 → 评估 → 设计 → 实施 → 验证 → 说明
+```
+
+1. **需求分类**:功能/修复/性能/重构/文档
+2. **检索**:相关类型、目录、方法、已有扩展/工具(**优先复用**)
+3. **评估**:是否公共 API?是否性能热点?**是否存在潜在问题?**
+4. **设计**:列出改动点 + 兼容/降级策略
+5. **实施**:
+   - 完成用户请求的核心任务
+   - **顺带修复**发现的明显缺陷(资源泄漏、空引用、逻辑错误)
+   - **顺带优化**可简化的重复代码
+   - 保留原注释与结构,除非注释本身有误
+6. **验证**:
+   - 代码变更:必须编译通过;运行相关单元测试(未找到需说明)
+   - 仅文档变更(未修改任何代码文件):可跳过编译与单元测试
+7. **说明**:变更摘要/影响范围/风险点
+
+### 4.1 主动优化原则
+
+当用户请求分析或优化代码时,**应主动**:
+
+| 类型 | 行动 |
+|------|------|
+| **架构梳理** | 梳理代码架构并进行重构,让代码结构更清晰易懂 |
+| **语法现代化** | 使用最新的 C# 语法来简化代码,提升可读性 |
+| **缺陷修复** | 资源泄漏、空引用风险、并发问题、逻辑错误 → 直接修复,让代码更健壮 |
+| **性能优化** | 无用分配、重复计算、可池化资源 → 通过缓存减少耗时的重复计算 |
+| **代码简化** | 重复代码提取、冗余判断合并、现代语法替换 → 在不影响可读性前提下简化 |
+| **注释完善** | 补充类、接口、属性、方法头部的注释,以及方法内部重要代码的注释 |
+| **架构参考** | 参考网络上同类功能的优秀架构,给出架构调整建议 |
+
+**架构调整策略**:
+- **改动较小**:直接调整,完成后说明变更内容
+- **改动较大**:先列出调整方案,询问用户意见,待确认后再修改
+
+**不应过度保守**:
+- ❌ 仅添加注释而忽略明显的代码问题
+- ❌ 发现资源泄漏却不修复
+- ❌ 看到重复代码却不提取
+- ❌ 用户要求优化时只做表面工作
+
+**保持谨慎的场景**:
+- 公共 API 签名变更 → 需说明兼容性影响
+- 性能关键路径 → 需有依据或说明推理
+- 大范围重构 → 需先与用户确认范围
+
+### 4.2 防御性注释规则
+
+在旧有代码中,经常可以看到**被注释掉的代码**,这些注释代码前面通常带有说明文字。
+
+**这些是防御性注释**:
+- 记录了过去曾经踩过的坑
+- 目的是告诉后来人不要按照注释代码去写,否则会有问题
+- **禁止删除此类防御性注释**,用于警示后人
+
+**识别特征**:
+```csharp
+// 曾经尝试过 xxx 方案,但会导致 yyy 问题
+// var result = DoSomethingWrong();
+
+// 不要使用 xxx,否则会造成 yyy
+// await client.SendAsync(data);
+
+// 这里不能用 xxx,因为 yyy
+// stream.Flush();
+```
+
+**处理原则**:
+- ✅ 保留这类带说明的注释代码
+- ✅ 可以补充更详细的说明,解释为什么不能这样做
+- ❌ 不要删除这类防御性注释
+- ❌ 不要尝试"恢复"这些被注释的代码
+
+---
+
+## 5. 编码规范
+
+### 5.1 基础规范
+
+| 项目 | 规范 |
+|------|------|
+| 语言版本 | `<LangVersion>latest</LangVersion>`,所有目标框架均使用最新 C# 语法 |
+| 命名空间 | file-scoped namespace |
+| 类型名 | **必须**使用 .NET 正式名 `String`/`Int32`/`Boolean` 等,避免 `string`/`int`/`bool` |
+| 兼容性 | 代码需兼容 .NET 4.5+;**禁止**使用 `ArgumentNullException.ThrowIfNull`,改用 `if (value == null) throw new ArgumentNullException(nameof(value));` |
+| 单文件 | 每文件一个主要公共类型;较大平台差异使用 `partial` |
+
+### 5.2 命名规范
+
+| 成员类型 | 命名规则 | 示例 |
+|---------|---------|------|
+| 类型/公共成员 | PascalCase | `UserService`、`GetName()` |
+| 参数/局部变量 | camelCase | `userName`、`count` |
+| 私有字段(实例/静态) | `_camelCase` | `_cache`、`_instance` |
+| 属性/方法(实例/静态) | PascalCase | `Name`、`Default`、`Create()` |
+| 扩展方法类 | `xxxHelper` 或 `xxxExtensions` | `StringHelper`、`CollectionExtensions` |
+
+### 5.3 代码风格
+
+```csharp
+// ✅ 单行 if:单语句且整行不过长时同行
+if (value == null) return;
+if (key == null) throw new ArgumentNullException(nameof(key));
+
+// ✅ 单行 if:语句较长时另起一行
+if (value == null)
+    throw new ArgumentNullException(nameof(value), "Value cannot be null");
+
+// ✅ 多分支单语句:不加花括号
+if (count > 0)
+    DoSomething();
+else
+    DoOther();
+
+// ✅ 循环必须保留花括号(即使单语句)
+foreach (var item in list)
+{
+    Process(item);
+}
+```
+
+### 5.4 Region 组织结构
+
+较长的类使用 `#region` 分段组织,顺序为:`属性` → `静态`(如有)→ `构造` → `方法` → `辅助`(如有)→ `日志`。
+
+**日志 Region 规则**:
+- 类代码中如果带有 `ILog Log { get; set; }` 和 `WriteLog` 方法
+- **必须放在类代码的最后**
+- **必须用名为"日志"的 region 包裹**
+- 不要放在"辅助" region 中,应单独作为"日志" region
+
+### 5.5 现代 C# 语法
+
+优先使用最新语法(switch 表达式、模式匹配、目标类型 `new`、record 等),即使目标框架是 net45。
+
+### 5.6 集合表达式
+
+优先使用集合表达式 `[]` 初始化集合:`List<String> Tags { get; set; } = [];`
+
+### 5.7 Null 条件运算符
+
+优先使用 `?.` / `??` 简化空值检查:`span?.AppendTag("test");` `var name = user?.Profile?.Name ?? "";`
+
+---
+
+## 6. 多目标框架
+
+NewLife 支持 `net45` 到 `net10`,常用条件符号:`NETFRAMEWORK`、`NETSTANDARD2_0`、`NETCOREAPP`、`NET5_0_OR_GREATER`、`NET6_0_OR_GREATER`、`NET8_0_OR_GREATER`。
+
+新增 API 时需评估各框架兼容性,必要时提供降级实现。
+
+---
+
+## 7. 文档注释
+
+| 规则 | 说明 |
+|------|------|
+| `<summary>` | **必须同一行闭合**,简短描述方法用途 |
+| `<param>` | **必须为每个参数添加**,无论方法可见性如何 |
+| `<returns>` | 有返回值时必须添加 |
+| `<remarks>` | 复杂方法可增加详细说明(可多行) |
+| 覆盖范围 | `public`/`protected` 成员必须注释;`private`/`internal` 建议添加 |
+| `[Obsolete]` | 必须包含迁移建议 |
+
+**正确示例**:`/// <summary>获取名称</summary>` `/// <param name="id">编号</param>`
+
+**禁止**:`<summary>` 拆成多行;缺少 `<param>`;有参数但无 param 标签。
+
+---
+
+## 8. 异步与性能
+
+| 规范 | 说明 |
+|------|------|
+| 方法命名 | 异步方法后缀 `Async` |
+| ConfigureAwait | 库内部默认 `ConfigureAwait(false)` |
+| 高频路径 | 优先对象池/`ArrayPool<T>`/`Span`,避免多余分配 |
+| 反射/Linq | 仅用于非热点路径;热点使用手写循环/缓存 |
+| 池化资源 | 明确获取/归还;异常分支不遗失归还 |
+
+**内置工具优先**:`Pool.StringBuilder`、`Runtime.TickCount64`、`ToInt()`/`ToBoolean()` 等扩展方法。
+
+---
+
+## 9. 日志与追踪
+
+规则:若类包含 `ILog Log` 与 `WriteLog`,必须放在类末尾,并用名为"日志"的 `#region` 包裹;关键过程可使用 `Tracer?.NewSpan()` 埋点。
+
+---
+
+## 10. 错误处理
+
+- **精准异常类型**:`ArgumentNullException`/`InvalidOperationException` 等
+- **参数校验**:空/越界/格式
+- **TryXxx 模式**:不用异常作常规分支
+- **类型转换**:优先使用 `ToInt()`/`ToBoolean()` 等扩展方法
+- **对外异常**:不暴露内部实现/路径
+
+---
+
+## 11. 测试规范
+
+| 项目 | 规范 |
+|------|------|
+| 框架 | xUnit |
+| 命名 | `{ClassName}Tests` |
+| 描述 | `[DisplayName("中文描述意图")]` |
+| IO | 使用临时目录;端口用 0/随机 |
+| 覆盖 | 正常/边界/异常/并发(必要时) |
+
+### 测试执行策略
+
+1. 优先检索 `{ClassName}` 引用,若落入测试项目则运行
+2. 未命中则查找 `{ClassName}Tests.cs`
+3. **未发现相关测试需明确说明**,不自动创建测试项目
+
+---
+
+## 12. NuGet 发布规范
+
+| 类型 | 命名规则 | 示例 |
+|------|---------|------|
+| 正式版 | `{主版本}.{子版本}.{年}.{月日}` | `11.9.2025.0701` |
+| 测试版 | `{主版本}.{子版本}.{年}.{月日}-beta{时分}` | `11.9.2025.0701-beta0906` |
+
+- **正式版**:每月月初发布
+- **测试版**:提交代码到 GitHub 时自动发布
+
+---
+
+## 13. Markdown 文档规范
+
+| 项目 | 规范 |
+|------|------|
+| 文件编码 | **必须** UTF-8,**禁止** GB2312/GBK/UTF-8 BOM |
+| 默认存放 | 代码库根目录下的 `Doc` 目录 |
+| 文件命名 | 优先**中文文件名**,简洁描述内容 |
+
+**注意**:已有文件**必须先读取**再增量修改,**禁止直接覆盖**。
+
+---
+
+## 14. Copilot 行为守则
+
+### 必须
+
+- 简体中文回复
+- 输出前检索现有实现,**禁止重复造轮子**
+- 先列方案再实现
+- 标记不确定上下文为"需查看文件"
+- **发现明显缺陷时主动修复**(资源泄漏、空引用、逻辑错误)
+- **用户要求优化时深入分析**,不做表面工作
+
+### 鼓励
+
+- 提取重复代码为公共方法
+- 简化冗余的条件判断
+- 使用现代 C# 语法改进可读性
+- 补充缺失的资源释放逻辑
+- 修正错误或过时的注释
+
+### 禁止
+
+- 虚构 API/文件/类型
+- 伪造测试结果/性能数据
+- 擅自删除公共/受保护成员
+- 擅自删除已有代码注释(除非注释本身错误)
+- **删除防御性注释**(带说明的注释代码,记录历史踩坑经验)
+- 仅删除空白行制造"格式优化"提交
+- 删除循环体的花括号
+- 将 `<summary>` 拆成多行
+- 将 `String`/`Int32` 改为 `string`/`int`
+- 新增外部依赖(除非说明理由并给出权衡)
+- 在热点路径添加未缓存反射/复杂 Linq
+- 输出敏感凭据/内部地址
+- **发现问题却视而不见**
+- **用户要求优化时仅做注释/测试等表面工作**
+
+---
+
+## 15. 变更说明模板
+
+提交或答复需包含:
+
+```markdown
+## 概述
+做了什么 / 为什么
+
+## 影响
+- 公共 API:是/否
+- 性能影响:无/有(说明)
+
+## 兼容性
+降级策略 / 条件编译点
+
+## 风险
+潜在回归 / 性能开销
+
+## 后续
+是否补测试 / 文档
+```
+
+---
+
+## 16. 术语说明
+
+| 术语 | 定义 |
+|------|------|
+| **热点路径** | 经性能分析或高频调用栈确认的关键执行段 |
+| **基线** | 变更前的功能/性能参考数据 |
+| **顺带修复** | 在完成主任务过程中,修复发现的相关问题 |
+| **防御性注释** | 被注释掉的代码,前面带有说明,记录历史踩坑经验,用于警示后人 |
+
+---
+
+## 17. 代码优化检查清单
+
+当进行代码优化时,按以下清单逐项检查:
+
+### 架构与结构
+- [ ] 代码架构是否清晰?是否需要重构?
+- [ ] 类的职责是否单一?是否需要拆分?
+- [ ] 是否有重复代码可以提取为公共方法?
+- [ ] Region 组织是否符合规范(属性→静态→构造→方法→辅助→日志)?
+
+### 语法现代化
+- [ ] 是否可以使用更简洁的 C# 语法?(switch 表达式、模式匹配等)
+- [ ] 集合初始化是否使用了集合表达式 `[]`?
+- [ ] 是否可以使用 null 条件运算符 `?.` 简化代码?
+
+### 健壮性
+- [ ] 是否存在空引用风险?
+- [ ] 资源是否正确释放?(IDisposable、流、连接等)
+- [ ] 异常处理是否完善?
+- [ ] 并发场景是否线程安全?
+
+### 性能
+- [ ] 是否存在可以缓存的重复计算?
+- [ ] 是否有不必要的对象分配?
+- [ ] 热点路径是否避免了反射和复杂 Linq?
+- [ ] 是否使用了对象池/ArrayPool 等池化技术?
+
+### 注释与文档
+- [ ] 类、接口是否有 `<summary>` 注释?
+- [ ] 公共方法是否有完整的参数和返回值注释?
+- [ ] 方法内重要逻辑是否有注释说明?
+- [ ] 防御性注释是否保留?
+
+### 日志
+- [ ] `ILog Log` 和 `WriteLog` 是否放在类的最后?
+- [ ] 是否用名为"日志"的 region 包裹?
+
+---
+
+(完)