I keep running into a lot of wierd issues while programing against AutoCAD. Here's the latest one.
The code just checks to see if a layer exists and if not, creates it. This code creates an error in AutoCAD. I get a message box that says 'Error Handler re-entered'. Which crashes AutoCAD. I do have time to pause the debugger and it happens inside the End Using statement, wich I will assume the crash is happening during the call to the transactions .Dispose() method.
Using tr As Transaction = dwg.TransactionManager.StartTransaction Dim lt As LayerTable = CType(tr.GetObject(dwg.LayerTableId, OpenMode.ForRead), LayerTable) If lt.Has(Name) Then Return Else Dim ly As New LayerTableRecord ly.Name = Name lt.UpgradeOpen() lt.Add(ly) tr.AddNewlyCreatedDBObject(ly, True) End If tr.Commit() End Using
However, the following code works without error:
Using tr As Transaction = dwg.TransactionManager.StartTransaction Dim lt As LayerTable = CType(tr.GetObject(dwg.LayerTableId, OpenMode.ForRead), LayerTable) If Not lt.Has(Name) Then Dim ly As New LayerTableRecord ly.Name = Name lt.UpgradeOpen() lt.Add(ly) tr.AddNewlyCreatedDBObject(ly, True) End If tr.Commit() End Using
The only difference being, in the first example if the name already exists, the transaction is not committed (although it shouldn't matter because nothing was changed) if the name exists, so it has to rollback when it's disposed.
I feel like this is an AutoCAD side bug. Does anyone else have any experience with such error?
And before you ask, yes, all my non-database resident object are disposed of properly. And no, I'm not accessing objects outside the transaction they were created/opened in.
Solved! Go to Solution.
Solved by Irvin. Go to Solution.
Your code works fine here.
Make sure you are locking the current the drawing.
Sub CreateLayer(ByVal name As String) Dim DWG As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Using lock As DocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument Using tr As Transaction = DWG.TransactionManager.StartTransaction Dim lt As LayerTable = CType(tr.GetObject(DWG.Database.LayerTableId, OpenMode.ForRead), LayerTable) If lt.Has(name) Then Return Else Dim ly As New LayerTableRecord ly.Name = name lt.UpgradeOpen() lt.Add(ly) tr.AddNewlyCreatedDBObject(ly, True) End If tr.Commit() End Using End Using End Sub
Hello there,
I think he is checking if the layer in an eventhandler. If so that's the reason he gets this error.
Furter information would be nice.
Kind regards,
irvin
It was being called from an ObjectErased handler, which was called during an undo operation. Basically my code is a product configurator, the action is they deleted the production, then hit undo, so (although this is strange to me) the ObjectErased event is called with the DBObjects IsUndoing property set to true, so I have to rebuild the product.
So your saying I can create and commit a transaction in an event handler, but rolling it back would crash AutoCAD?
No transaction in Eventhandlers is what Autodesk prefers.
What you could do is use the CommandEnded event.
This is triggerd after the command is finished.
Kind regards,
Irvin