现象

首先这是一段测试代码,它的内容是随便画一个对象,然后调用cad的command将它删除。

[CommandMethod(nameof(Test1))]
public static void Test1()
{
    var doc = Acap.DocumentManager.MdiActiveDocument;
    var ed = doc.Editor;
    for (var i = 0; i < 200; i++)
    {
        ObjectId id;
        {
            using var tr = doc.Database.TransactionManager.StartTransaction();
            var csp = (BlockTableRecord)tr.GetObject(doc.Database.CurrentSpaceId,
                OpenMode.ForWrite);
            var cir = new Circle(Point3d.Origin, Vector3d.ZAxis, 100);
            id = csp.AppendEntity(cir);
            tr.AddNewlyCreatedDBObject(cir, true);
            tr.Commit();
        }
        // 调用commanmd删除
        ObjectId[] ids = [id];
        var ss = SelectionSet.FromObjectIds(ids);
        ed.Command("erase", ss, "", "");
        ss.Dispose();
        ss = null;
        ed.WriteMessage($"{i}\n");
    }
}

可以尝试一下,这段代码跑到中间的时候,会弹出“调用的目标发生了异常”的错误,然后cad的选择集就无法使用了。
原因是cad的选择集不能超过128个,但是可以看到我的代码里加了dispose释放了变量,但是仍然不行,c#也没有提供释放选择集的api。

我尝试使用com接口获取文档中的选择集,发现数量居然是0。
此问题只会在使用 SelectionSet.FromObjectIds 函数时才会出现,使用editor.GetSelection拿到的选择集不会出现此问题。
并且只有使用editor.Command后才会出现,单纯的创建选择集无论创建多少个也不会出现错误,可能是非拖管对象发送到c++端使用后没有释放,这很可能是cad的一个bug。

解决方法

无法解决,只能不用。ed.Command的时候不传选择集,将id一个一个传进去也是一样的。

// 原写法
ObjectId[] ids = [id];
var ss = SelectionSet.FromObjectIds(ids);
ed.Command("erase", ss, "", "");
// 替代写法
List<object> commandList = ["erase", ..ids, "", ""]; 
ed.Command(commandList.ToArray());

这样要先构建一个commandList,都添加完之后ToArray转为数组再传到editor.Command的参数里。
麻烦了那么一点点。