Hi,
I have a reactor that responds to stretching a dynamic block.
The problem is that it takes 4 undo commands to revert any stretch change.
Command: _u
Command: _u GROUP
Command: _u REGENALL
Command: _u Grip Edit
Without posting an entire project, does anyone have any suggestions on what the problem might be or a simple solution?
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Solved by ActivistInvestor. Go to Solution.
I think you're going to have to provide a bit more detail.
I'm not sure what you mean by a 'reactor', and I don't think there's much anyone can tell you without seeing at least the part of the code modifies the database.
You should also check to see if you can REDO the UNDO.
@SRSDSwrote:Hi,
I have a reactor that responds to stretching a dynamic block.
The problem is that it takes 4 undo commands to revert any stretch change.
Command: _u
Command: _u GROUP
Command: _u REGENALL
Command: _u Grip Edit
Without posting an entire project, does anyone have any suggestions on what the problem might be or a simple solution?
Sorry, by reactor I meant an event. I've narrowed it down.
It's because I have a transaction within the ImpliedSelectionChanged event which requires three undo operations on any event.
If I comment the transaction out everything behaves normally.
Is it not good practice to have a transaction in the ImpliedSelectionChanged event? I can't think of an alternative.
I don't think anything is triggering the ImpliedSelectionChanged but it is a possibility. Should it get triggered on any enitity modification?
Correction. Not any event.
A grip change event triggers the ImpliedSelectionChanged event, which results in three undos required:
Command: _u
Command: _u GROUP
Command: _u Grip Edit
You're not supposed to use a 'regular' transaction in an event handler.
But you can use an OpenCloseTransaction, as it doesn't use the UNDO mechansim.
Instead of calling StartTransaction(), call StartOpenCloseTransaction().
However, modifying objects from within the ImpliedSelectionChanged event could have other adverse side-effects.
@SRSDSwrote:Sorry, by reactor I meant an event. I've narrowed it down.
It's because I have a transaction within the ImpliedSelectionChanged event which requires three undo operations on any event.
If I comment the transaction out everything behaves normally.
Is it not good practice to have a transaction in the ImpliedSelectionChanged event? I can't think of an alternative.
I don't think anything is triggering the ImpliedSelectionChanged but it is a possibility. Should it get triggered on any enitity modification?
I've hit a problem since adding StartOpenCloseTransaction on this line.
Dim Ent As Entity = ObjID.GetObject(OpenMode.ForRead)
The Try...Catch handler doesn't register. It just ejects out of the subroutine.
Would there be any issue if I replaced all instances of
Dim Ent As Entity = ObjID.GetObject(OpenMode.ForRead)
with
Dim Ent As Entity = trans.GetObject(ObjID, OpenMode.ForRead)
It's taking a while to debug other instances where transactions aren't closing and it would be easiest if I did a replace all.
No, there's non issue if trans is a 'regular' transaction (i.e., not an OpenCloseTransaction).
Dim Ent As Entity = ObjID.GetObject(OpenMode.ForRead)
is a shortcut for:
Dim Ent As Entity = db.TransactionManager.TopTransaction.GetObject(ObjID, OpenMode.ForRead)
While the ObjectId's GetObject() method might be a convenient way to avoid the need to have a reference to the 'top transaction', it's also slower, mainly because in reality, this is what it's doing:
ObjectId id = ... DBObject obj = id.Database.TransactionManager.TopTransaction.GetObject(id, OpenMode.ForRead);
It's not a problem for 'casual' use, but will be slower when opening many objects in a loop. So, my recommendation would be to avoid that method and use transactions directly, because doing so gives you the option of using either a regular or OpenCloseTransaction, and more-easily change from one to the other.
@SRSDSwrote:Would there be any issue if I replaced all instances of
Dim Ent As Entity = ObjID.GetObject(OpenMode.ForRead)with
Dim Ent As Entity = trans.GetObject(ObjID, OpenMode.ForRead)It's taking a while to debug other instances where transactions aren't closing and it would be easiest if I did a replace all.
I'm sure there's nothing wrong with this but I only use the one 'top level' transaction for each command and pass it through all subroutines.
trcnt=0
Using trans As Transaction = db.TransactionManager.StartTransaction : trcnt = trcnt + 1 MySub(trans) trans.Commit() : trcnt = trcnt - 1 : If trcnt > 0 Then MsgBox("TRCNT>0") End Using
Probably cons to it but at least I get feedback if a transaction wasn't interrupted.
Love to know how you guys do it because debugging for me is incredibly painful.