检查清单 | Checklist
功能描述 | Description
> 声明:本 issue 由 AI 协助测绘与撰写,全部数据已由本人人工复核,PR 由本人提交并对内容负责。
> - [x] 您没有为软件提交 Pull Request 或开发插件的能力(我能提交 PR,此项按表单要求勾选,特此说明)
一句话功能描述
希望能把挤在 MainWindow 里的计时、截图、热键这些功能逐步拆成独立的小模块,让代码更好维护、bug 更容易排查,全程不改变大家用起来的任何感受。
总原则
纯结构重构,零行为变化 。不改 UI、不改用户可感知的任何流程、不修 bug。过程中若发现疑似 bug,单独开 issue 记录,绝不顺手改——否则 diff 无法审查,回归无法归因。
小步快走 :拆成可能约 12 个工作阶段,每阶段一个独立分支、一个独立 PR、可单独 revert,不与任何其他改动混在一起。
每阶段有明确门禁 :构建零错误 + 受影响功能人工冒烟通过,才进入下一阶段;某阶段出问题,只回退该阶段。
需求动机 | Motivation
背景与动机
对 net10 主线做了一次较完整的代码测绘(以当前 1.8.0.9 为准,数字动工前会再复核):
MainWindow 是一个巨型 partial 类:本体约 3,700 行,Ink Canvas/MainWindow_cs/ 下还有 58 个 partial 文件,合计约 5.8 万行。计时、截图、热键、托盘、通知、设置读写、PPT 集成都寄生在主窗体上;
全库有 323 处空 catch(分布在 86 个文件),异常被静默吞掉——issue 区不少"玄学无法复现"的反馈(如 选择并拖拽墨迹后有概率导致墨迹始终处于可拖动状态 #662 、在白板中选择并尝试缩放墨迹时墨迹异常 #654 )与这种状态散落直接相关:不是没法修,是根本没有可诊断的信息;
139 个文件直接引用 Dispatcher,线程归属靠约定而非结构保证;
116 个辅助类平铺在 Helpers 目录下,没有按业务域划分。
带来的实际代价:修一个计时器问题要在一个 5 万行的类里干的昏天黑地;新贡献者很难安全地改代码;很多 bug 不是不能修,是不敢修。这次重构想解决的就是"不敢改"的问题。
期望设计 | Expected Design
阶段计划 | Plan
风险三档:🟢 机械操作、行为不变;🟡 结构移动、行为不变;🔴 涉及语义敏感区域的等价改写。
阶段
内容
风险
PR 方式
1
重构规范文档 + 可复现的构建基线
🟢
随首个代码 PR 附带
2
文件名规范化(消灭文件名中的 &)与 MainWindow_cs 目录语义修正
🔴 blame 断裂
单独一个 PR,纯 git mv
3
csproj 语言版本对齐到 C# 12
🟢
可独立合入
4
Helpers 按域分组(Ink / Ppt / Update / Security / UiShell)
🟡 纯移动零改动
每域一个 PR
5
从 MainWindow 提取低耦合服务:设置存储、托盘、通知、计时、截图、热键
🟡
每服务一个 PR
6
工具模式从字符串比较改为强类型枚举(持久化格式原样不动)
🟡
独立 PR
7
323 处空 catch 分 5 批治理(记日志 / 重抛 / 注释说明为何吞)
🟢
每批一个 PR,建议从这批开始审
8
PPT 集成(MW_PPT.cs)逐步提取为独立服务
🔴 耦合最高
分段合入,先讨论
9
ROTPPTManager(约 3,000 行)、AutoUpdateHelper(约 2,900 行)按职责拆 partial
🟡
各一个 PR
10
已提取服务中的 Dispatcher 直引收敛到统一调度入口
🔴 线程语义敏感
需讨论
11
xUnit 测试项目 + 纯逻辑代码首批单元测试
🟢
一个 PR
12
全量 diff 审计、Release 构建、冒烟清单、合入
🟢
—
完成后预期:MainWindow 体量下降 40% 以上,新增代码集中在 Services/ 下、与 UI 解耦、可单测。
三个高风险项,单独交代
这三处是改动最大、最容易出问题的地方,先说清楚做法和红线;任何一项如果不被认可,直接砍掉不影响其余阶段。
① 计时器服务化(阶段 5 的一部分)
把计时核心从 MW_Timer.cs(约 1,800 行)提取为独立的 TimerService:剩余时间、tick 递减、暂停语义收为不依赖 UI 的纯逻辑,窗口显隐留在主窗体。
红线:定时器类型原样搬移 ,不做 DispatcherTimer 与线程池 Timer 之间的互换(那是线程来源变化,不是等价改写);Tick 里碰 UI 的点统一收拢到入口方法,替换前后逐一核对。
预期收益:现在"暂停后 Tick 泄漏""停止后回调重入"这类隐患只能靠自觉避免,服务化后"任何时刻至多一个活跃 Tick"由结构保证。
验证:构建通过 + 服务内 Dispatcher/MainWindow 引用为零 + 新旧实现跑同一组计时场景(开始 → 运行 → 暂停 → 继续 → 结束)剩余时间序列逐秒一致,验证记录随 PR 附上。
② 文件改名(阶段 2)
代价是 git blame 在这些文件上断裂。补偿措施:纯 git mv,一个 commit 都不夹带逻辑改动,git log --follow 可以追历史;整个改名独立成一个 PR,方便一次性决定接受或拒绝。
③ Dispatcher 收敛(阶段 10)
只把已提取服务里直接引用 Dispatcher 的 UI 更新点改走统一调度入口——只换调用路径,不动线程模型;每一处替换都可以独立 revert。
测试承诺
严格遵守 CONTRIBUTING.md 中对大规模重构的全部要求:
每个 PR 附 Release 构建通过证明;
对重构涉及的功能做完整测试(UI 改动按三步法:样式、行为、i18n);
对所有变更点做回归可能性检查;
测试中发现的问题逐 commit 核对、针对性修复,不盲目改、不带病合入;
每个 PR 附人工冒烟清单(画板、墨迹、橡皮、PPT 模式、计时器、截图、热键等实际受影响的面)。
边界与取舍
请维护者拍板
按上表的颗粒度逐阶段提 PR 是否合适?还是更希望压缩成少数几个大 PR?
阶段 2 的改名 PR,能否接受 blame 断裂的代价?
三个高风险项(计时器、PPT 拆分、Dispatcher 收敛)是否需要先做小范围试点再展开?
什么时间窗口开始比较合适(避开在途 PR 冲突)?
没有回复的话,我默认按"先提阶段 7 空 catch 治理的第一批 PR 试水"起步——它风险最低、收益最直接,也正好验证协作流程。
其他补充信息 | Additional Info
No response
上传有关文件 | Upload relevant files
No response
检查清单 | Checklist
功能描述 | Description
> 声明:本 issue 由 AI 协助测绘与撰写,全部数据已由本人人工复核,PR 由本人提交并对内容负责。
> - [x] 您没有为软件提交 Pull Request 或开发插件的能力(我能提交 PR,此项按表单要求勾选,特此说明)
一句话功能描述
希望能把挤在 MainWindow 里的计时、截图、热键这些功能逐步拆成独立的小模块,让代码更好维护、bug 更容易排查,全程不改变大家用起来的任何感受。
总原则
需求动机 | Motivation
背景与动机
对 net10 主线做了一次较完整的代码测绘(以当前 1.8.0.9 为准,数字动工前会再复核):
MainWindow是一个巨型 partial 类:本体约 3,700 行,Ink Canvas/MainWindow_cs/下还有 58 个 partial 文件,合计约 5.8 万行。计时、截图、热键、托盘、通知、设置读写、PPT 集成都寄生在主窗体上;catch(分布在 86 个文件),异常被静默吞掉——issue 区不少"玄学无法复现"的反馈(如 选择并拖拽墨迹后有概率导致墨迹始终处于可拖动状态 #662、在白板中选择并尝试缩放墨迹时墨迹异常 #654)与这种状态散落直接相关:不是没法修,是根本没有可诊断的信息;Dispatcher,线程归属靠约定而非结构保证;带来的实际代价:修一个计时器问题要在一个 5 万行的类里干的昏天黑地;新贡献者很难安全地改代码;很多 bug 不是不能修,是不敢修。这次重构想解决的就是"不敢改"的问题。
期望设计 | Expected Design
阶段计划 | Plan
风险三档:🟢 机械操作、行为不变;🟡 结构移动、行为不变;🔴 涉及语义敏感区域的等价改写。
&)与MainWindow_cs目录语义修正git mvMW_PPT.cs)逐步提取为独立服务ROTPPTManager(约 3,000 行)、AutoUpdateHelper(约 2,900 行)按职责拆 partialDispatcher直引收敛到统一调度入口完成后预期:MainWindow 体量下降 40% 以上,新增代码集中在
Services/下、与 UI 解耦、可单测。三个高风险项,单独交代
这三处是改动最大、最容易出问题的地方,先说清楚做法和红线;任何一项如果不被认可,直接砍掉不影响其余阶段。
① 计时器服务化(阶段 5 的一部分)
把计时核心从
MW_Timer.cs(约 1,800 行)提取为独立的TimerService:剩余时间、tick 递减、暂停语义收为不依赖 UI 的纯逻辑,窗口显隐留在主窗体。红线:定时器类型原样搬移,不做
DispatcherTimer与线程池 Timer 之间的互换(那是线程来源变化,不是等价改写);Tick 里碰 UI 的点统一收拢到入口方法,替换前后逐一核对。预期收益:现在"暂停后 Tick 泄漏""停止后回调重入"这类隐患只能靠自觉避免,服务化后"任何时刻至多一个活跃 Tick"由结构保证。
验证:构建通过 + 服务内
Dispatcher/MainWindow引用为零 + 新旧实现跑同一组计时场景(开始 → 运行 → 暂停 → 继续 → 结束)剩余时间序列逐秒一致,验证记录随 PR 附上。② 文件改名(阶段 2)
代价是 git blame 在这些文件上断裂。补偿措施:纯
git mv,一个 commit 都不夹带逻辑改动,git log --follow可以追历史;整个改名独立成一个 PR,方便一次性决定接受或拒绝。③ Dispatcher 收敛(阶段 10)
只把已提取服务里直接引用
Dispatcher的 UI 更新点改走统一调度入口——只换调用路径,不动线程模型;每一处替换都可以独立 revert。测试承诺
严格遵守
CONTRIBUTING.md中对大规模重构的全部要求:边界与取舍
请维护者拍板
没有回复的话,我默认按"先提阶段 7 空 catch 治理的第一批 PR 试水"起步——它风险最低、收益最直接,也正好验证协作流程。
其他补充信息 | Additional Info
No response
上传有关文件 | Upload relevant files
No response