Skip to content

修复内存溢出风险:帧队列单生产者、串口无锁队列、Serilog 文件日志,并优化日志 UI 高频打印卡顿 - #55

Merged
ca1e merged 15 commits into
EasyConNS:devfrom
zhantss:dev
Aug 14, 2026
Merged

Conversation

@zhantss

@zhantss zhantss commented Aug 14, 2026

Copy link
Copy Markdown

背景:针对画面捕获、日志、多线程三处内存溢出与性能风险做审查后,分功能改造如下。

画面捕获:单生产者最新帧队列

  • 新增 EasyCon.Capture/FrameStore(单槽最新帧 + Interlocked 引用计数,保证每个原生 Mat 恰好释放一次)与 FrameProducer(后台采集循环,阻塞 Read 自然控速)。
  • 所有消费者(画面预览 / 图像匹配 / OCR / 截图 / AI / CLI)统一改为从队列「租约取帧」,不再各自直接调 GetMatFrame,消除共享锁争用与每帧重复 Clone。
  • 修复原生 Mat 泄漏(Mat 无 finalizer,未释放即永久泄漏);采集循环在设备断开/无帧时自动降频,避免空转。

串口:无锁发送队列

  • TTLSerialClient 的 List<byte[]> + lock + Thread.Sleep(1) 改为 ConcurrentQueue<byte[]>(无锁入队/出队)。
  • 新增 IConnection.ClearQueue();脚本终止(含停止、出错、取消)统一触发设备 Reset():释放全部按键并清空待发队列,避免卡键与残留报文。

日志:Serilog 文件日志 + 有界 UI 环形缓冲

  • 采用 Serilog.Sinks.File 落盘:按日期 + 文件大小滚动切分(logs/easycon-*.log),文件为完整记录。
  • UI 改为有界环形缓冲(上限 10000 行),Flush 批量封顶(单批最多 500 行),高频打印时不再拖垮 UI;CLI 输出同步写文件。

日志 UI 性能优化

  • TerminalControl 最大行宽改为增量缓存(消除加行时的 O(n²) 全量测量)。
  • 行宽按字体版本缓存(每行 FormattedText 只测一次);纯文本行跳过 ANSI 解析器。
  • Serilog 开启 buffered,脚本线程不再每行同步写盘。

健壮性

  • FrameProducer.Dispose 增加保护:采集循环卡在阻塞 Read(设备停滞)时跳过底层 VideoCapture 释放,避免 use-after-release 崩溃。

验证

  • 全解决方案构建 0 错误;EasyCon.Tests 644 通过 / 0 失败。
  • 手动验证:高频 FOR/PRINT/NEXT 下 UI 保持响应(完整记录仍落盘);脚本中途停止按键立即释放、无残留报文。

zhantss added 15 commits August 13, 2026 19:47
…oducer + lease); convert preview/match/OCR/screenshot/CLI consumers
…pt stop (Reset releases buttons + drops pending HID)
…, eliminating O(n²) scroll recalc on log bursts
…tch, skip ANSI parse for plain lines, cache line width, buffer Serilog
@ca1e
ca1e merged commit 1aed001 into EasyConNS:dev Aug 14, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants