aardio 文档

LISP 任务:提交、回执与恢复

com.cad.task 在兼容 CAD 的 COM 命令通道之上执行 AutoLISP,并通过本地文件返回数据。它不依赖 Autos、特定窗口类名、Visual LISP COM 函数接口或 .NET 插件。回执确认的是程序执行和序列化结果,不代替几何或业务验收。

建议入口

增强实例入口可省略doc,此时只使用已有活动图纸,不自动新建;底层task.create仍要求显式doc。code 是原始 LISP 源码,不是 aardio 模板,也不是文件名。最后一个表达式的值为结果,args 是 LISP 中的局部变量。不要使用 ac$ 前缀的内部变量,也不要在任务中切换/关闭目标图纸或嵌套提交任务。

最小完整示例

import com.cad;
import com.cad.task;
var cad = com.cad();
if(!cad) error("无法连接或启动 CAD");
if(!cad.IsQuiescent()) error("CAD 当前忙碌,请先检查原任务");
var doc = cad.Documents.Add(); // 本例明确新建测试图纸。
var task,err = cad.CreateLispTask(
    `(list (cons "text" (car args)) (cons "answer" (+ (cadr args) 5)))`,
    ["中文",7],doc
);
if(!task) error(err);
// 在提交前持久化路径;进程意外退出也能重新查回执。
var recoveryFile = io.appData("aardio/com.cad/last-task.txt",task.path);
print("任务目录",task.path);
var sent,err = task.submit();
if(!sent) {
    print("提交未确认,勿重发",err,task.path);
    return;
}
var result,err = task.wait();
print(result,err); // completed 时 data 为 {text="中文";answer=12}

恢复时只读原任务,不另建 ID 重试:

import com.cad.task;
var path,err = string.load(io.appData("aardio/com.cad/last-task.txt"));
if(!path) error(err);
var task,err = com.cad.task.open(path);
if(!task) error(err);
var result,err = task.wait(5000);
print(result,err);

read() 和默认的 wait() 只读取任务目录,不读取 COM 文档;省略 doc 打开的任务始终可以离线等回执。wait() 泵送窗口/STA 消息,不使用长时间纯 sleep。只有创建时显式设 nudge=true 且仍持有原 doc 时,wait 才可能刷新命令队列(见下文)。收到回执后 CAD 仍可能正在退出包装器;后续 COM 查询如被暂时拒绝,可有限重试无副作用查询,不重放任务源码。

RunLisp与技能调用同一com.cad.task.run/runTask,journal位于 %LOCALAPPDATA%\aardio\com.cad\journal。底层create只指定doc时不猜产品,默认post/utf8;通常使用增强实例入口。详见兼容说明。

状态与返回值

state 意义
prepared 已创建,本机尚无提交标记
submitted 已认领一次提交机会;不证明 CAD 已接收或执行
running CAD 已写 started 标记,尚无终态回执
completed 执行与结果序列化成功,ok=true、terminal=true
error parse / execute / serialize / transport 等阶段失败,terminal=true
rejected CAD 端发现不是原目标文档或实例
expired 超过最迟开始时间,未进入用户源码
cancelled CAD 在执行用户源码前接受了取消请求
timeout 本次 wait 等待超时;terminal=false,observedState 保留实际快照

read() 失败返回 null,err。wait() 对非成功终态返回 result,err;超时也返回快照及错误说明,而不是伪造终态。请检查 result.ok 和 result.terminal,不要只检查 result 是否非 null。CAD 端语法检查会拒绝括号不完整、未闭合字符串/块注释、额外右括号,避免原始源码破坏传输表达式。

超时、去重与取消

options

字段 默认值 说明
directory %LOCALAPPDATA%\aardio\com.cad\tasks 其下创建唯一请求目录;应使用 CAD 和调用方都可读写的本地路径
method AutoCAD/浩辰post,中望send 创建时按增强实例ProgId选择,显式值优先;提交失败后不换方法重放
timeout 10000 wait 默认等待毫秒数,0 表示立即查询;最大 86400000
startTimeout 30000 从创建时计算的最迟开始毫秒数;最大 86400000
nudge false true 才允许 wait 自动刷新未开始的 Post 队列;需要原 doc,会同步调用 SendCommand,可能阻塞
nudgeDelay 800 显式启用 nudge 时,从本次 wait 开始等候的毫秒数;0有效,最大86400000
resultEncoding AutoCAD utf8,中望/浩辰 ansi UTF-8要求支持三参数open;ANSI受代码页限制,先验证文字往返
codepage 本机系统 ANSI 代码页 resultEncoding="ansi" 时用于解码,应与 CAD 输出一致
idleTimeout 3000 RunLisp/runTask前后有限等空闲,0不额外等待;不能打断阻塞COM

method=send 的 COM 调用本身可能阻塞;wait 的超时无法打断一个尚未返回的 COM 方法。PostCommand 也不构成硬实时保证。 强隔离要求应由调用方使用独立工作进程实现,而不是让底层库绑定 Autos。对不兼容的 CAD 先做纯查询小探针,不静默降级或修改安全设置。

队列刷新是显式选项,不是默认兜底

PostCommand 排队到空闲时处理;向非活动文档提交时可能使目标文档成为活动文档,不保证保持当前文档不变。submitted 未开始也可能是交互输入、模态窗口、许可证或系统阻塞,不能一概归因命令通道。优先查原任务及环境,不重发业务源码。

确需刷新时,com.cad.task.open(path,doc) 得到原任务,再调用 task.nudge()。它只对仍 submitted 的 post 任务发送 (princ) 空操作;核对文档名称、文档/应用 HWND,要求原目标仍活动且 CAD 空闲。不激活其他文档,不发送任务源码;成功后记录 nudged。

创建时 nudge=true 可让每次 wait 在达到 nudgeDelay 后最多尝试一次;已有 nudged 标记不再刷新。默认false,旧请求缺少该字段同样不刷新。wait(0) 仅查询,不刷新;超时快照可能含 nudgeError 说明未能刷新的原因。成功刷新也不代表业务完成,仍以原终态回执为准。

nudge 使用同步 SendCommand,可能驱动该实例中其他已排队命令;COM 调用未返回时,wait 超时无法中断它。 如要求纯异步等待,请保持默认值。刷新不等于 Esc、任务取消或回滚。

性能:区分 CAD 内执行和端到端耗时

减少跨进程往返有利于批量工作,但不能把 LISP 循环耗时等同于任务总耗时。2026-09-19 本机 AutoCAD 2026 对照:均新建300个相同的圆、返回300个Handle、缓存ModelSpace、统一重生成一次,三轮交错测量:

这里完整任务从创建到收到回执计时;当时版本LISP内绘图及重生成仅47–110毫秒,不能将它当作端到端耗时。这是2026-09-19传输优化时的runner与数据;后续增加结果类型支持后命令长度不同,不能把旧基准当作后续版本的新测量。

这是单机测量,不是性能保证。完整任务还包含代码生成、提交、CAD 排队、序列化和回执等待。适合批量合并操作,不宜把每个实体都拆成一次任务;少量对象可直接 COM。不要为了缩短等待时间而取消完成确认,也不要把 method=send 当作无条件更快、更安全的替代。

数据协议和限制

目录和恢复边界

目录保存 request.json、command.txt、submitted、started、result.json,以及可选 cancel/submit-error.txt/nudged。命令文件在发送前校验哈希,结果先关闭临时文件再改名发布。

目录内含代码、参数和结果,可能包含敏感信息;由调用方控制访问与保留期限。只在确认终态且不再需要审计/恢复后主动清理。禁止自动删除未知任务的目录。硬盘损坏、文件被手工修改、CAD 退出、身份句柄复用等不在“只执行一次”的保证范围内。

文档绑定同时检查文档名称、文档 HWND、应用 HWND;不依赖标题和窗口类名。关闭重开图纸、另存改名或重启 CAD 后,不应提交之前 prepared 的任务,应先人工/业务核对。若原任务 submitted/running,始终以核对回执和实际图纸为先,不能直接重放。

Markdown 格式