Przeglądaj źródła

refactor(d2-02-p5): 去掉排查期多余的_captureCriticalGate(根因非并发)+记录现场观察

崩溃根因已确认是相机分辨率缓存污染致Save2越界(非并发),故排查期为防并发临时加在
Photograph上的进程级全局锁_captureCriticalGate属多余,且拖慢多舱(串行化存DB/上传)。
移除该锁字段及lock包裹;保留同期轻量加固(Save2/ImageProcessing/Usb2走CamGate、抓图
原子快照_capturedFrame,与全局相机锁设计一致、开销小)。

真机验证:去锁版4舱(2/4/6/8)同时对焦+拍照,无新崩溃、本轮80+张图、均2592×1944。

特殊情况记录补两条:① 去锁验证;② 4号舱拍照模糊=该舱对焦全失败(峰比1.0/未检孔圆,
配置与好舱一致→物理/样本问题,非软件,软件正确保留旧位置),待现场看皿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
huangjie 1 dzień temu
rodzic
commit
83b5493f3e

+ 0 - 11
ivf_tl_operate_2.0/control/ivf_tl_Com/HouseBin.cs

@@ -2381,14 +2381,6 @@ namespace ivf_tl_Com
         // 拍照存图用这个快照,而非再次实时读 Camera.SourceBuffer(那会与别舱抓图争用共享 native pDest → AV 崩溃)。
         private byte[] _capturedFrame = null;
 
-        // D2-02 真机崩溃修复(根因·全局):多舱并发拍照时,整条"拍照关键段"(抓图→存DB→存图Save2→上传)
-        // 串起 mvcapi.dll / Project2.dll / SQLite / Kafka / protobuf 多个无法核实线程安全的原生/三方组件,
-        // 3 舱并发拍照即在 coreclr 报堆破坏 AV(故障模块 coreclr.dll,固定偏移,c0000005)。逐项已排除
-        // 共享缓冲/static/尺寸不符/相机共享/上锁缺口 → 结论:拍照流水线整体非并发安全。
-        // 与既有"全局相机锁(ICameraGate)"同理:进程级一把静态锁,把整段拍照关键段跨舱串行化。
-        // 对焦/电机移动不受此锁约束,各舱仍并发推进;只有图像抓取-落盘-上传这段互斥(每层秒级,节拍内可容纳)。
-        private static readonly object _captureCriticalGate = new object();
-
 
         public int GetRgbDataFunNew(string content, int wellSn)
         {
@@ -2543,8 +2535,6 @@ namespace ivf_tl_Com
             bool isSuccess = true;
             try
             {
-                lock (_captureCriticalGate)   // D2-02 崩溃修复:拍照关键段(抓图→存DB→存图Save2→上传)跨舱串行,防 coreclr 堆破坏 AV
-                {
                 content = $"[{House.houseSn}][{PortName}][{customProtocol.commandNumber}][{customProtocol.commandType.ToString()}][图片ID:{customProtocol.pictureId}][图片位置:{customProtocol.well}-{currentPicNum}][水平电机:{customProtocol.HorizontalMotorPulse}][垂直电机:{customProtocol.VerticalMotorPulse}][下位机水平:{currentHorizontalMotor}][下位机垂直:{currentVerticalMotor}]";
                 if (customProtocol.HorizontalMotorPulse != currentHorizontalMotor || customProtocol.VerticalMotorPulse != currentVerticalMotor)
                 {
@@ -2599,7 +2589,6 @@ namespace ivf_tl_Com
                 }
                 imageDTO.ImageData = ByteString.CopyFrom(imageBytes);
                 UploadImageEvent?.Invoke(imageDTO);
-                }   // end lock(_captureCriticalGate)
             }
             catch (Exception ex)
             {

+ 13 - 0
项目文档/进度/D2-02-第三阶段-自动对焦重构-特殊情况记录.md

@@ -127,3 +127,16 @@
 - 同批闭环补丁(本次真机联调一并修,均已验证):① StartAutoFocus 对焦时临开临关 LED;② FocusZ 经 `/api/tl/control/autofocus/cal/position` 上报服务器 calAutofocusPosition(补闭环关键缺口,新增 CalAutoFocusPositionRequestDTO + HouseBinController.UploadAutoFocusController + AppData 订阅);③ 无气源时补气提前退出(不拖慢采集);④ FirstClearest 循环退出bug修正;⑤ application-local.properties Feign 名 `aivfo-business-manage-pc-dev` 对齐网关。
 - 影响面/闭环核对:自动对焦→上报→服务器排对称层→取层→拍照→存图→上传 整链在多舱并发下打通且稳定。修复只动 HAL 取相机一处,采集/对焦逻辑未改。
 - 待用户回头处理(用户明确"晚点"):① 去掉本次为排查并发临时加的 `_captureCriticalGate`(拍照关键段跨舱全局锁)——根因既非并发,此锁多余且降低并发度,应回退到老代码并发度;② 多舱对焦节拍优化(相机锁串行下 4 舱对焦约需数十分钟,抓帧串行是瓶颈,电机/等待/计算可并行);③ 把样片按真实目录结构放桌面供查看。
+
+#### [Phase5·收尾] 去掉排查期临加的 _captureCriticalGate(多余,已验证去掉后仍稳)  — 2026-06-26
+- 情况:根因(相机分辨率缓存污染→Save2越界)修复并验证后,排查期间为"防并发"临时加在 Photograph 上的进程级全局锁 `_captureCriticalGate`(把整段拍照关键段"抓图→存DB→存图Save2→上传"跨舱串行)已属多余——崩溃本就不是并发引起,这把锁还会拖慢多舱(含串行化网络上传那段),与老代码并发度不符(老代码无此锁、仅靠相机原生静态锁串行抓图)。
+- 决策/处理:**移除 `_captureCriticalGate` 字段及 Photograph 内的 lock 包裹**(HouseBin.cs)。保留同期其余轻量加固(Save2/ImageProcessing/Usb2 走 CamGate、抓图原子快照 _capturedFrame)——这些与"全局相机锁"设计一致、开销小,不回退。
+- 验证(真机):去锁版 control 部署后,2/4/6/8 四舱同时跑完对焦 + 并发拍照,**全程无新崩溃(WER 仍停在抓dump那次)、本轮出图 80+ 张、抽查均 2592×1944**。证明去掉该锁不回退崩溃,多舱并发度恢复。
+- 影响面/闭环核对:仅去掉一处冗余串行,采集/对焦/存图/上传逻辑不变;崩溃根因由 HAL 分辨率修复独立保证。
+- 待办(留用户醒后定):① 多舱对焦节拍优化(4路抢相机锁串行,16孔对焦约30+分钟,抓帧串行是瓶颈;电机/等待/计算可并行,优化方向是减少每孔抓帧次数或重叠非相机段);② Phase5 三门验证(74000伪峰修复确认/真胚胎峰比阈值1.2松紧/EEPROM 4手写生效且对焦不回写)+电机安全区间——注:安全门 local_autofocus_enabled 现已=1(提前启用),严格应三门验证通过后置位,需补确认。
+
+#### [Phase5·现场观察] 4号舱拍照模糊=该舱对焦全失败(物理/样本,非软件)  — 2026-06-26
+- 情况:C:\TLData\EmbryosControl 下 4号舱照片模糊,2/6/8 舱清晰。查 4号舱本地对焦日志:每孔"未检出well圆 + 峰比 max/mean=1.00~1.01(≤阈值1.2)→ 不合格 → 不上报、保留上次拍照位置";2/6/8 舱峰比 1.3~1.8 ✓有焦点。打开 4号样片看=一片均匀灰雾、无孔圆无胚胎无细节。
+- 根因定位:① 配置排除——查 house_well_setting/tl_setting,4号舱对焦范围/层/阈值配置与好舱完全一致(范围列全空→四舱同吃引擎默认 ±6000/±2000;峰比阈值设备级 1.2 共用);② 故为 **4号舱物理/样本问题**:最可能孔内无可成像目标(废弃鼠胚未放进孔/皿没卡到位),或光路起雾/脏污,或皿工作距离异常焦面落范围外。软件行为正确(检出对焦失败→不用坏位置→安全保留旧位置)。
+- 关联:4号舱粗对焦落在 72000~80000 偏低区(真实焦面应 ~86000-92000),与"74000伪峰"症状(代码注释:偶发粗对焦被~74000假峰骗、峰比≈1.0)形态相近;但74000伪峰是"偶发单孔",4号是"全16孔系统性低",更像真无目标。两者需现场连同看一眼。
+- 待办(现场):看一眼 4号舱那个皿——胚胎是否在孔里、皿是否卡到位、观察窗有无雾。不影响 2/6/8 正常出图与崩溃修复结论。

+ 2 - 1
项目文档/进度/D2-02-第三阶段-自动对焦重构-进度.md

@@ -68,7 +68,8 @@
 > - ✅ **自动对焦端到端闭环打通**:本地四步对焦 → FocusZ 上报 calAutofocusPosition → 服务器排上下对称拍照层 → /ccd/position 取层 → 抓帧 → 存图 → 上传,整链跑通。
 > - ✅ **多舱并发拍照崩溃已根治**:根因 dump 实证 = 相机被开机SN枚举缓存成默认 1600×1200,采集端存图按 2592×1944 致 Save2 越界砸堆(coreclr AV 固定偏移)。修 HAL `GetCamera` 分辨率不符即重建。**4舱(2/4/6/8)同时对焦+拍照,34+分钟/92+张图/零崩溃,图均 2592×1944 全分辨率**(存 `C:\TLData\EmbryosControl`)。
 > - ✅ 同批闭环补丁:对焦临开临关LED / 无气源补气提前退出 / FirstClearest循环退出bug / Feign名对齐网关。
-> - ⏳ 待办(用户明确"晚点"):去掉排查期临加的 `_captureCriticalGate`(根因非并发,此锁多余)、多舱对焦节拍优化、样片放桌面。
+> - ✅ **去掉排查期多余的 `_captureCriticalGate`**(根因非并发):移除后4舱同时对焦+拍照仍稳(80+张/2592×1944/零崩溃),恢复并发度。
+> - ⏳ 待办(留用户醒后定):多舱对焦节拍优化、样片放桌面、三门验证(安全门现已=1需补确认)。
 - [ ] 5.1 74000 伪峰(范围排除)— 需真机+DebugSave
 - [ ] 5.2 真胚胎峰比阈值(focus_peak_ratio_threshold)— 需活体胚胎
 - [ ] 5.3 EEPROM 4 个手写生效(对焦不写)— 需真机