Author Topic: Rules on transactions etc.  (Read 613 times)

0 Members and 1 Guest are viewing this topic.

AlexFielder

  • Mosquito
  • Posts: 11
Rules on transactions etc.
« on: February 06, 2024, 11:10:46 AM »
Hi all,

I've been seeing quite a good bit of success with the addin I mentioned starting to write back in August, but just lately I have a bunch of examples where I will place a blockreference in a drawing, and it just disappears moments later.

In and around the placement, a bunch of things happen- namely placing a dimension or two and depending upon the situation it may or may not draw a line or some piece of text (mainly for my own debugging purposes) and I wondered if someone has some general rules on transactions and use of the AutoCAD database in general.

Years ago on here I think it was Daniel or someone else who said something like "if you 'new' it, dispose of it or commit" or words to that effect.

One method I have which occasionally produces "invisible" blocks is this:

Code: [Select]
public void InsertBlockReference(MasonryBracketSystemViewModel systemDefinition, Matrix3d transformMatrix, BlockReference blkRef)
        {
            Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                if (blkRef != null)
                {
                    blkRef.TransformBy(transformMatrix);

                    blkRef.SetDatabaseDefaults();
                    modelSpace.AppendEntity(blkRef);
                    tr.AddNewlyCreatedDBObject(blkRef, true);
                    var attrInfos = new Dictionary<string, AttrInfo>();

                    SetBlockRefAttributeValuesBasedOnParameters(systemDefinition, false, tr, blkRef, out attrInfos);

                    SetBlockRefDynPropsBasedOnParameters(systemDefinition, 0, blkRef);
                    blkRef.RecordGraphicsModified(true);

                    AddXRecordToBlockReference(blkRef, "systemName", systemDefinition.AssignedSystemName.SystemName);
                    AddXRecordToBlockReference(blkRef, "instanceNumber", systemDefinition.AssignedSystemName.InstanceNumber);
                    AddXRecordToBlockReference(blkRef, "level", systemDefinition.AssignedSystemName.Level);

                    SetXRecordsUsingViewModel(systemDefinition, blkRef);

                    modelSpace.UpdateAnonymousBlocks();
                    ed.Regen();
                    ed.UpdateScreen();
                    db.Regenmode = true;
                    db.UpdateExt(true);
                    tm.QueueForGraphicsFlush();
                    tr.Commit();
                }
                else
                {
                    throw new System.Exception("The block reference was null");
                }
            }
        }

(db in this case is external to that method but I wonder whether it should in fact be local?):

Code: [Select]
public static Database db; // = HostApplicationServices.WorkingDatabase;
        public static Document doc; // = Application.DocumentManager.MdiActiveDocument;
        public static Editor ed;

        public BlockHelpers()
        {
            uXSettings = new UXSettings();
            doc = CadApp.DocumentManager.MdiActiveDocument;
            db = doc.Database;
            ed = doc.Editor;
        }

57gmc

  • Bull Frog
  • Posts: 366
Re: Rules on transactions etc.
« Reply #1 on: February 07, 2024, 12:16:19 PM »

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Rules on transactions etc.
« Reply #2 on: February 07, 2024, 02:42:07 PM »
If you are adding the block to the blocktable from another dwg then the db is best to be local

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Rules on transactions etc.
« Reply #3 on: February 07, 2024, 10:01:44 PM »
Alex, I believe the Commit is in the incorrect place

Make it the last statement in the Using code block.
That may not be the cause of the irregularity but it will be conventional.

Some light reading
https://help.autodesk.com/view/OARX/2024/ENU/?guid=GUID-24B217B9-EC4D-4BE9-AC05-89265B3BE6B6
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Rules on transactions etc.
« Reply #4 on: February 10, 2024, 03:01:43 PM »

(db in this case is external to that method but I wonder whether it should in fact be local?):


I usually make a DB property of a class with a CommandClass attribute since one is created for each document it used and lends itself to pointing to correct database when used.


AlexFielder

  • Mosquito
  • Posts: 11
Re: Rules on transactions etc.
« Reply #5 on: February 18, 2024, 10:01:37 AM »
Thank you for the replies all; apologies for not getting back to this sooner- I don't receive "reply" notification emails to my gmail account for some reason.

I realised after lots of testing that the commit was indeed in the wrong place:

Code - C#: [Select]
  1. public void InsertBlockReference(MasonryBracketSystemViewModel systemDefinition, Matrix3d transformMatrix, BlockReference blkRef)
  2.         {
  3.             Document doc = Application.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.             Editor ed = doc.Editor;
  6.  
  7.             var btrId = db.GetBlockId(systemDefinition.AssignedSystemName.ToString());
  8.  
  9.             Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
  10.             using (Transaction tr = db.TransactionManager.StartTransaction())
  11.             {
  12.                 BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  13.                 if (blkRef != null)
  14.                 {
  15.                     blkRef.TransformBy(transformMatrix);
  16.  
  17.                     blkRef.SetDatabaseDefaults();
  18.                     modelSpace.AppendEntity(blkRef);
  19.                     tr.AddNewlyCreatedDBObject(blkRef, true);
  20.  
  21.                     var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  22.                     var attDefclass = RXObject.GetClass(typeof(AttributeDefinition));
  23.  
  24.                     var attDefs = btr
  25.                         .Cast<ObjectId>()
  26.                         .Where(id => id.ObjectClass == attDefclass)
  27.                         .Select(id => (AttributeDefinition)id.GetObject(OpenMode.ForRead))
  28.                     .ToArray();
  29.  
  30.                     SetBlockRefAttributeValuesBasedOnParameters(systemDefinition, false, blkRef, attDefs);
  31.  
  32.                     //SetBlockRefAttributeValuesBasedOnParameters(tr, systemDefinition, false, blkRef);
  33.  
  34.                     //SetBlockRefDynPropsBasedOnParameters(systemDefinition, 0, blkRef);
  35.                     blkRef.RecordGraphicsModified(true);
  36.  
  37.                     modelSpace.UpdateAnonymousBlocks();
  38.                     ed.Regen();
  39.                     ed.UpdateScreen();
  40.                     db.Regenmode = true;
  41.                     db.UpdateExt(true);
  42.                     tm.QueueForGraphicsFlush();
  43.                     tr.Commit();
  44.  
  45.                     AddXRecordToBlockReference(blkRef, "systemName", systemDefinition.AssignedSystemName.SystemName);
  46.                     AddXRecordToBlockReference(blkRef, "instanceNumber", systemDefinition.AssignedSystemName.InstanceNumber);
  47.                     AddXRecordToBlockReference(blkRef, "level", systemDefinition.AssignedSystemName.Level);
  48.  
  49.                     SetXRecordsUsingViewModel(systemDefinition, blkRef);
  50.                 }
  51.                 else
  52.                 {
  53.                     throw new System.Exception("The block reference was null");
  54.                 }
  55.             }
  56.         }

And it is the wrong place because the Xrecord functions* take in the now-placed BlockReference and add the data to it.

Edit: *each of which start and commit their own transaction by the way.

edit,Kerry : code tag [ code = csharp ]
« Last Edit: February 18, 2024, 02:40:47 PM by kdub_nz »