明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 372|回复: 0

[图形系统] cad.net 查找异常/回放动作/统计命令

[复制链接]
发表于 2025-3-17 17:55:56 | 显示全部楼层 |阅读模式
本帖最后由 你有种再说一遍 于 2025-3-19 19:15 编辑

在cad.net开发中,
由于大部分人都没有接受过训练就上战场,
例如引入不同的包功能,使得项目变得越来越复杂.
同时还允许我们比Lisp更自由操作内存(非托管内存).
这样使得一旦出问题,我们debug非常困难.

一些常规的规范操作,
例如能using就绝对不手工释放.
要手工释放的就最好写入Disposable的派生类中,
外部执行using,从而达到规范化.

还有一些难以启齿的错误,
由于.net不是可观可测系统,
我们不能直接通过GC内存使用前后量来判断.
也无法像C++一样重定向new关键字,
此时就需要挂不同的事件进行debug了.

利用:
命令前事件,记录命令到日志.
命令结束后,记录命令到日志.

当发生异常的时候,
你检查日志就可以知道哪个命令没有正常结束,
或者命令结束后仍然发生了错误,也可以检查命令链.

例如内存泄露并不是必显的,
这样起码缩小范围到命令链中多个命令.

一些不良习惯喜欢把
var a = new...
a = new... // 弄丢了原始指针
a.Dispose()

再例如,我们通过tr.GetObject(id)进行打开对象,
那么哪个命令打开对象之后没有释放呢?
我们就可以挂命令后事件,
然后每次检查一次这个tr.GetAllObjects()数量,
数量不为0才报错.

如果觉得每次触发命令都序列化太伤硬盘,
我们就利用消息队列,传递给其他进程让其惰性序列化.
毕竟宕机是少数,我们保护等级不需要像数据库一样每每写入.

利用统计,除了日志找bug之外.
还可以回放动作,看看播放你全部命令之后,能否复现问题.
还可以优化频率高的命令,从而改变你的"画图手法".

命令是Acad系统中重要概念,
命令实际上是一个消息队列,
它会投递到在Acad主线程中执行,
而界面上面触发,要发送命令,而不是直接执行函数,
函数的运行不一定在主线程触发.
这关系到线程上下文问题.
CommandFlags中有无历史命令,你可以隐匿在界面的执行.

事件可以拦截cad自带的命令,
而消息过程可以拦截函数异常,
Fody可以拦截报错.
例如重置用户配置后发生错误.
此类错误还可以尝试去钩一下消息过程,
毕竟经常勾着它,它可能给你带来不一样debug点子.

xx
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-3-30 01:05 , Processed in 0.191595 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表