Author Topic: Crash when undoing custom command.  (Read 2713 times)

0 Members and 1 Guest are viewing this topic.

zoltan

  • Newt
  • Posts: 188
Crash when undoing custom command.
« on: April 13, 2012, 05:20:23 PM »
I have a command that created a number of layouts, inserts xrefs and block and generally does a lot of stuff by committing lots of transactions.  When I try to undo the command, AutoCAD crashes with this error:

INTERNAL ERROR: !dbsymblk.cpp@1062: eNullObjectId

Has anyone seen this before?

TheMaster

  • Guest
Re: Crash when undoing custom command.
« Reply #1 on: April 13, 2012, 09:48:16 PM »
Hard to speculate on what's happening, but you might want to try avoiding
starting and committing many transactions and rather, use just one that
encapsulates the entire operation.

I have a command that created a number of layouts, inserts xrefs and block and generally does a lot of stuff by committing lots of transactions.  When I try to undo the command, AutoCAD crashes with this error:

INTERNAL ERROR: !dbsymblk.cpp@1062: eNullObjectId

Has anyone seen this before?

zoltan

  • Newt
  • Posts: 188
Re: Crash when undoing custom command.
« Reply #2 on: April 18, 2012, 09:13:55 PM »
I don't think that it would be possible to do everything in one transaction.  I have to import a layout from a template.  That layout has to be in the database in order to get one of its viewports.  I insert a block and then edit its dynamic properties and attributes.  The block has to be in the database.  There are just so many steps that require the transaction to be committed before the next step is valid.


MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Crash when undoing custom command.
« Reply #3 on: April 19, 2012, 07:52:43 AM »
Example of how I try to use one transaction.
Code: [Select]
using (Transaction tr = db.TransactionManager.StartTransaction())
{
    ImportLayout(tr);

    GetLayoutViewport(tr);

    InsertBlockandEditProperties(tr);

    tr.commit();
}

You should only have to call tr.Commit() once anyway. Anything else that needs info created from the transaction gets done during tr.AddNewlyCreatedObject().
Revit 2019, AMEP 2019 64bit Win 10

kaefer

  • Swamp Rat
  • Posts: 572
Re: Crash when undoing custom command.
« Reply #4 on: April 19, 2012, 08:14:55 AM »
I find it pretty cumbersome to pass the Transaction around.

Either the command is implemented as an instance method, then there could be a private field in which to store it on a per-document basis (C#),
or it gets use-bound in a closure and the helpers are defined in its scope (F#),
or it may be generally possible to refer to Autodesk.AutoCAD.DatabaseServices.TransactionManager.TopTransaction for the same purpose.

zoltan

  • Newt
  • Posts: 188
Re: Crash when undoing custom command.
« Reply #5 on: April 19, 2012, 09:00:34 AM »
I have tried the single transaction idea and it causes other problems like eHasTooManyReaders and eAlreadyOpenForWrite.  The only way I could get this to work was to break it up into multiple transactions.

 

TheMaster

  • Guest
Re: Crash when undoing custom command.
« Reply #6 on: April 19, 2012, 12:28:26 PM »
I don't think that it would be possible to do everything in one transaction.  I have to import a layout from a template.  That layout has to be in the database in order to get one of its viewports.  I insert a block and then edit its dynamic properties and attributes.  The block has to be in the database.  There are just so many steps that require the transaction to be committed before the next step is valid.

None of the operations you describe have any dependence on
a transaction encapsulating previous operations being committed.

Objects become database-resident before transactions are committed,
they are resident as soon as you call the API that adds them to their
owner and returns their ObjectId.

In case you didn't know it, a Transaction is merely a wrapper around
the UNDO/Begin and UNDO/End commands.  The only reason why one
would need to use multiple transactions, is if they wanted to be able
to abort some operations without also aborting previous operations.



« Last Edit: April 19, 2012, 12:33:28 PM by TheMaster »

BlackBox

  • King Gator
  • Posts: 3748
Re: Crash when undoing custom command.
« Reply #7 on: April 25, 2012, 10:32:47 AM »
Came across this, and thought it to be relevant here, given Tony's last post...

Use transaction from a sub function
By Adam Nagy
 
If you start a transaction inside your main function, then you do not need to create another one (a sub transaction) inside your sub function, you do not even need to pass the transaction to the sub function, you can simply use ObjectId.GetObject() instead, which will automatically use the outer transaction you started.
< .. code follows .. >
"How we think determines what we do, and what we do determines what we get."