阻止插入循环错误

时间:2014-10-14 07:37:02

标签: c# .net autocad

美好的一天,

我正在创建一个Autocad csharp程序,用于计算几个级别并在用户点击的位置插入一个块,并在while循环中执行此操作,以便用户可以继续选择要计算的新点和插入。只有它在用户指定的第一点才能完美运行,但是当他们点击另一个点时,会弹出错误消息" eInvalidOpenState。"并且该程序取消。有谁熟悉这个以及它为什么会发生?

我已经添加了程序的一小部分,问题出在那里,你可以看到它在做什么。

*编辑:我已经添加了锁并删除了dispose,但仍然使while循环的原始错误无法正常工作。整个程序第一次正常工作,在第二次循环时,它请求用户指定该点,当用户执行此操作时崩溃并给出以下错误消息:

**************例外文字************** Autodesk.AutoCAD.Runtime.Exception:eInvalidOpenState    在Autodesk.AutoCAD.DatabaseServices.DBObject.UpgradeOpen()    at Level_Arrow.Program.InsertBLock(String [] args)在c:\ Users + \ Documents \ Visual Studio 2013 \ Projects \ Level Arrow \ Level Arrow \ myCommands.cs:第94行    at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi,Object commandObject,Boolean bLispFunction)    at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi,Object commandObject,Boolean bLispFunction)    在Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

if (drgUnits == "mm")
{
    while (drgUnits == "mm")
    {
        using (tr)
        {
            PromptPointOptions ptIns = new PromptPointOptions("");
            ptIns.Message = "\nSpecify insertion point: ";
            PromptPointResult ptInsert = ed.GetPoint(ptIns);

            if (ptInsert.Status == PromptStatus.Cancel) return;

            double yInsert = ptInsert.Value.Y;

            Scale3d blkScale = new Scale3d(drgScalemm, drgScalemm, drgScalemm);
            ObjectId bdId = bt[blkName];
            Point3d pt = ptInsert.Value;

            BlockReference insblkref = new BlockReference(pt, bdId);
            insblkref.ScaleFactors = blkScale;
            insblkref.Rotation = 0;

            btr.UpgradeOpen();
            btr.AppendEntity(insblkref);
            btr.DowngradeOpen();
            tr.AddNewlyCreatedDBObject(insblkref, true);

            if (OrgBtr.HasAttributeDefinitions)
            {
                foreach (ObjectId id in OrgBtr)
                {
                    DBObject obj = tr.GetObject(id, OpenMode.ForRead);
                    AttributeDefinition ad = obj as AttributeDefinition;

                    if (ad != null && !ad.Constant)
                    {
                        AttributeReference ar = new AttributeReference();
                        ar.SetAttributeFromBlock(ad, insblkref.BlockTransform);
                        ar.Position =ad.Position.TransformBy(insblkref.BlockTransform);
                        if (ad.Justify != AttachmentPoint.BaseLeft)
                        {
                            ar.AlignmentPoint.TransformBy(insblkref.BlockTransform);
                        }
                        if (ar.IsMTextAttribute)
                        {
                            ar.UpdateMTextAttribute();
                        }
                        ar.TextString = ptDisp.ToString();
                        ObjectId arId =  insblkref.AttributeCollection.AppendAttribute(ar);                         
                        tr.AddNewlyCreatedDBObject(ar, true);
                        break;
                    }
                }
            }

            tr.Commit();
            tr.Dispose(); 
        }
    }
}

2 个答案:

答案 0 :(得分:1)

从代码中很难理解(它似乎不完整)并且您没有提到异常的来源,但是从快速的一瞥看起来有可能tr你被处置后正在访问对象。

在任何情况下,当您使用using()时,您都不需要处置或关闭。

答案 1 :(得分:0)

更新时应锁定活动文档。使用using语句确保它处理。大多数AutoCAD功能都是这样的。在VB语法中:

    Using lock = Acdoc.lockdocument
      Using trans = acdoc.TransactionManager.starttransaction
          <<do your stuff>>
      end using
    end using