In the past C++/C era, it was very easy to crash AutoCAD or even the whole Operating System. Now in the .NET time, it is harder, much harder than before, but we still can find various ways to crash AutoCAD using its .NET API, from the easiest or most common to quite hard or very creative.
Previously, we crashed AutoCAD through disposing of every disposable BRep object as far as the AutoCAD Boundary Representation .NET API is concerned. We also presented the very similar code except for without disposing of those BRep objects and found that it seemed to work fine.
The thing is, is it really all fine?
Let’s try to figure it out this time. Here is the sample code again for reference.
[CommandMethod("SeemsFine10")]
public static void SeemsFine10_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
try
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
RXClass solidRxClass = RXObject.GetClass(typeof(Solid3d));
foreach (ObjectId id in btr)
{
if (id.ObjectClass == solidRxClass)
{
Solid3d solid = (Solid3d)tr.GetObject(id, OpenMode.ForRead);
Autodesk.AutoCAD.BoundaryRepresentation.Brep brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(solid);
{
ed.WriteMessage("\nObjectId of the solid: {0}", id);
Autodesk.AutoCAD.DatabaseServices.Surface surface = brep.Surf;
//using (surface)
{
ed.WriteMessage("\n\tSurface area: {0}", surface.GetArea());
}
foreach (Autodesk.AutoCAD.BoundaryRepresentation.Face face in brep.Faces)
{
//using (face)
{
ed.WriteMessage("\n\tFace IsOrientToSurface: {0}", face.IsOrientToSurface);
foreach (Autodesk.AutoCAD.BoundaryRepresentation.BoundaryLoop loop in face.Loops)
{
//using (loop)
{
ed.WriteMessage("\n\tBoundaryLoop type: {0}", loop.LoopType);
foreach (Autodesk.AutoCAD.BoundaryRepresentation.Edge edge in loop.Edges)
{
//using (edge)
{
//using (edge.Curve)
{ ed.WriteMessage("\n\t\tEdge curve type: {0}", edge.Curve.GetType()); }
//using (edge.Vertex1)
{ ed.WriteMessage("\n\t\t\tVertext1: {0}", edge.Vertex1.Point); }
//using (edge.Vertex2)
{ ed.WriteMessage("\n\t\t\tVertext2: {0}", edge.Vertex2.Point); }
}
}
}
}
}
}
}
}
}
tr.Commit();
}
}
catch (System.Exception ex)
{
ed.WriteMessage(Environment.NewLine + ex.Message);
}
}
As we saw last time, the test command ran well for the first time. Let’s do a few more runs this time and see what will happen. To make things clear and avoid mistrust, some simple LISP code has been created to repeat the same command many times without any interruptions or user interactions in between.
(setq count 0)(repeat 10 (print (setq count (+ count 1)))(command "SeemsFine10" "ReGen"))
Here is finally we got!
As can be seen, at some time later instead of at the very first try on our end, the AutoCAD 2012 crashed. We did not do anything else except for calling the very test command followed with a ReGen. It might be even later if without the ReGen call or simply to try the same in a different AutoCAD version/flavor or simply at a different time, but please don’t worry about all these anyway. Please just increase the repeat counter bigger, to e.g. 50 or 100, and you will not miss the crash at the end.
So, we got AutoCAD crash with or without disposing of BRep objects. What should we do then? Any ideas from any body (expert)?
It is not really a bad thing even to pretend to be in case the altitudes look equal, the discussions sound open, and the audiences are broad enough. It will finally get things sorted out rather than more convoluted.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Posted by: |