Atook 发表于 2020-10-9 02:58:02

处理属于组的实体时出现致命错误。

我在处理对象时看到一个致命错误。当我访问某些对象时,它会断断续续地发生,我怀疑这些对象总是一组的一部分。在附图中,我指出了可以复制的对象。
在附图中处理多段线时,此代码崩溃。
公共静态句柄GetHandle(ObjectId id)
{
句柄应答=新句柄()
如果(id==ObjectId.Null)返回答案
Document doc=Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument
数据库db=doc.Database
使用(Transaction acTr=db.TransactionManager.StartTransaction())
{
var obj=acTr。GetObject(id,OpenMode.ForRead)
答案=对象句柄
调试。WriteLine($“句柄:{answer.ToString()}”)
acTr.Commit()//
//类型为“System”的未处理异常。accoremgd.dll中发生“AccessViolationException”
//其他信息:试图读取或写入受保护的内存
//这通常表示其他内存已损坏。
}
返回答案
}
我开始怀疑我创建组的方式是可疑的
我创建组的方式是:
//
///创建一个以名称为前缀,后跟数字的组。
//
//
//
公共静态void CreateAnonymousGroup(ObjectdCollection GroupEntId,字符串前缀)
{
如果(!groupEntId.Contains(ObjectId.Null))
{
Document doc=Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument
数据库db=doc.Database
使用(Transaction tr=db.TransactionManager.StartTransaction())
{
DBDictionary-groupDictionary=(dbdictional)tr.GetObject(db.groupdictoriayid,OpenMode.ForWrite,true)
int number=groupDictionary.Count
字符串groupName=前缀+数字
if(IsValidSymbolName(groupName))
{
while(groupDictionary.Contains(groupName))//不允许重复的groupName
{
number++
groupName=前缀+数字
}
//我们现在大概可以添加它了。
groupgrp=新组(groupName,true)
组字典。SetAt(组名,grp)
tr.addNewlyCreatedBobObject(grp,true)
玻璃钢。InsertAt(0,groupEntId)
}
tr.Commit()
}
}
}
知道我的错误在哪里吗?
**** Hidden Message *****

MickD 发表于 2020-10-9 05:42:21

我能想到的就是尝试使用for循环并追加实体,而不是使用插入,至少作为测试。我已经使用组多年了,没有遇到这样的麻烦。
Group.InsertAt上的帮助有点晦涩难懂,因为它说:
在我看来,这就像你需要找到组条目的末尾,并在该索引
之后
添加,如果“0”索引为空,那么......
我还将组设置为“可选”,但我认为在直接查询数据库时不会有太大区别。
hth

n.yuan 发表于 2020-10-9 11:42:43

我使用句柄2D44对多段线运行了GetHandle()方法,代码如下:
public static void TestCrash()
      {
            var dwg = Application.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;
            var res = ed.SelectAll(
                new SelectionFilter(
                  new Autodesk.AutoCAD.DatabaseServices.TypedValue[]
                  {
                        new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)DxfCode.LayoutName, "MODEL")
                  }));
            if (res.Status== PromptStatus.OK)
            {
                foreach (ObjectId id in res.Value.GetObjectIds())
                {
                  if (id.Handle.ToString().ToUpper()=="2D44")
                  {
                        var h = GetHandle(id); //This is your code
                  }
                }
            }
      }

我没有崩溃。既然你说它是间歇性的,我想你还没有找到一个一致的方法来复制它。然而,我在这里确实有几个问题:
1.GetHandle(ObjectId)方法的用途是什么?也许这里只是为了测试,以证明在提交事务时,组中多段线的特定ObjectId是崩溃的根源?因为该方法本身没有任何商业意义:如果您在memry中有一个ObjectId,那么您已经知道了它的句柄。所以,我认为你只是为了证明崩溃而编造出来的,并没有在任何实际工作中真正使用它。但我还是问了。
2.当我看到像GetHandle()这样的代码,其中ObjectId作为参数传递,但在方法内部(对于外部调用方来说,它应该是一个黑盒),代码仍然为操作数据库拾取MdiActiveDocument时,我感到非常不舒服:ObjectId已经提供了一个到ObjectId有效的数据库的路径,为什么需要将该方法绑定到MdiActiveDocument的数据库?这将有效地限制此方法只能与MdiActiveDocument一起使用,而不能用于任何打开的数据库,例如您编写代码运行的辅助数据库。也就是说,您可以使该方法在MdiActiveDocument或side数据库中有用,如果您这样做:<br>公共静态void对实体(ObjectId entId)<br><<br>使用(var-tran=entId.<strong>数据库</strong>TransactionManager.StartTransaction()〕<br>,<<br>tran.Commit();<br<trans><br>这也让我好奇:您可能是,在数据库处理端调用GetHandle()方法时,是否有可能获得错误

Atook 发表于 2020-10-14 01:02:18

MickD:谢谢你输入组的创建,我t

n.yuan 发表于 2020-10-14 09:28:12

再次重申我的观点:
1。说实体(汉

Atook 发表于 2020-10-14 11:16:48

谢谢你的跟进,诺曼。
看来我弄错了导致崩溃的原因。当我在调试模式下复制错误时,这就是调试器在提交事务时爆发的地方。我的架构中一定有一些错误,导致了下游函数的问题。我不知道如何开始追查这些错误。我很感谢你花时间单独运行这个函数(从我的应用程序的stacktrace中),我会在下次发帖之前尝试这样做。
感谢您指出如何减少对活动文档的依赖,以及创建更通用的函数。对我来说,这看起来确实是更好的代码。
页: [1]
查看完整版本: 处理属于组的实体时出现致命错误。