.NET

Reply
Member
4 Posts
0 Kudos
Registered: ‎07-23-2012
Post 1 of 7

Crash when Transaction takes too long

498 Views, 6 Replies
07-24-2012 11:36 PM

Hello everyone,

 

i have got a problem with AutoCAD 2010 right now. Im having some procedures that take very long to process in between a TransactionManager.StartTransaction and Commit/Abort.

When taking too long AutoCAD sometimes just disappears/crashes without giving a call stack/Exception or anything. There are also no memory leaks or exceptions raised, though i send some status messages to the command line of AutoCAD.

 

Does AutoCAD need anything like a KeepAlive? Do i have to send it some specific messages or anything? Is that a common problem?

Distinguished Mentor
582 Posts
91 Kudos
Registered: ‎04-11-2010
Post 2 of 7

Re: Crash when Transaction takes too long

07-25-2012 06:52 AM in reply to: OrgadataPST

Hi,

 

Please show the code, and any other relevant information like platform, VS version, .NET Framework, drawing size (posting a sample dwg is very useful) , etc.

 

Gaston Nunez

 

 

Member
4 Posts
0 Kudos
Registered: ‎07-23-2012
Post 3 of 7

Re: Crash when Transaction takes too long

07-25-2012 07:19 AM in reply to: gasty1001

Sadly i can not provide the drawing, because it crashes where the drawing gets generated.

 

VS-Version: 2008 C# Standard

.NET: 3.5

 

And here is the C# code(modified though):

using (Transaction acTransaction = TransactionManager.StartTransaction())
            {
                try
                {
                    CurrentTransaction = acTransaction;

                    BlockTableRecord acBlockTableRecord = acTransaction.GetObject(BlockIds.Peek(),
                            OpenMode.ForWrite) as BlockTableRecord;                    

                    // Create a new object
                    Region acRegion = GetProfileRegion(profile);
                    Polyline3d acPath = GetExtrusionPath(profile.Axis);

                    Solid3d acSolid = new Solid3d();
                    acSolid.SetDatabaseDefaults();
                  
                    acSolid.ExtrudeAlongPath(acRegion, acPath, 0);

                    Solid3d acSlicedSolid = acSolid;
                    try 
                    {
                        SolidAnalyzer.GetFaceNormals(profile, acSolid);
                    }
                    finally
                    {
                        if (acSlicedSolid != null)
                            acSlicedSolid.Color = Autodesk.AutoCAD.Colors.Color.FromColor(profile.OuterColor);
                    }

                    // Append the newly created object to model space and active transaction
                    acBlockTableRecord.AppendEntity(acSlicedSolid);
                    acTransaction.AddNewlyCreatedDBObject(acSlicedSolid, true);

                    acRegion.Dispose();
                    acPath.Erase();

                    // Save changes to database and close transaction
                    acTransaction.Commit();
                    AutoCADApplication.Print("Profile: " + profile.Name + " successfully constructed.");
                }
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    AutoCADApplication.Print("Failed to construct profile " + profile.Name
                        + "\n" + ex.Message + "\n\n" + ex.StackTrace);
                    acTransaction.Abort();
                }
                finally
                {
                    CurrentTransaction = null;
                }

 

The GetProfileRegion and GetExtrusionPath Methods always work/never crashed before and i can´t post them for different reasons. The profile region is a highly detailed cut of a window profile.

The SolidAnalyzer class is defined as follows:

public static class SolidAnalyzer
    {
        private static string Vector3dToString(Vector3d vector)
        {
            return "[" +
                vector.X.ToString("F2") + ", " +
                vector.Y.ToString("F2") + ", " +
                vector.Z.ToString("F2")
                + "]";
        }
         
        private static Vector3d GetFaceNormal(Autodesk.AutoCAD.BoundaryRepresentation.Face face, Point3d point)
        {
            PointOnSurface ptOnSurf = face.Surface.GetClosestPointTo(point);
         
            Point2d param = ptOnSurf.Parameter;
         
            Vector3d normal = ptOnSurf.GetNormal(param);         
            Vector3d normalTest = normal.MultiplyBy(1E-6 / normal.Length);
          
            Point3d ptTest = point.Add(normalTest);
         
            PointContainment ptContainment = new PointContainment();
         
            bool reverse = false;
         
            using(BrepEntity brepEnt = face.Brep.GetPointContainment(ptTest, out ptContainment))
            {
                if(ptContainment != PointContainment.Outside)
                {
                    reverse = true;
                }
            }
         
            return normal.MultiplyBy(reverse ? -1.0 : 1.0);
        }

        public static List<Vector3d> GetFaceNormals(Profile profile, Solid3d profileSolid)
        {
            List<Vector3d> faceNormals = new List<Vector3d>();

            using (Brep brep = new Brep(profileSolid))
            {
                foreach (Autodesk.AutoCAD.BoundaryRepresentation.Face face in brep.Faces)
                {
                    PointContainment ptContainment = new PointContainment();

                    using (BrepEntity brepEnt = face.GetPointContainment(new Point3d(0, 0, 0), out ptContainment))
                    {
                        faceNormals.Add(GetFaceNormal(face, new Point3d(0, 0, 0)));

                        //if (ptContainment == PointContainment.Inside ||
                        //    ptContainment == PointContainment.OnBoundary)
                        {
                            AutoCADApplication.Print("\nFace Normal at " +
                                "[0, 0, 0] = " + Vector3dToString(GetFaceNormal(face, new Point3d(0, 0, 0))));
                        }
                    }
                }
            }

            return faceNormals;
        }
    }

 

After adding the SolidAnalyzer class and using GetFaceNormals AutoCAD sometimes first freezes/does not respond and then crashes or disappears after some normals have been written to the commandline.

 This procedure takes very long because the solid3d has >300 faces most of the time.

 

 

ADN Support Specialist
352 Posts
27 Kudos
Registered: ‎07-24-2007
Post 4 of 7

Re: Crash when Transaction takes too long

07-30-2012 04:14 PM in reply to: OrgadataPST

I have not run your code to test what's going on exactly, but i can guess just looking... Please see my comments below...

 

using (Transaction acTransaction = TransactionManager.StartTransaction())

{

    try

    {

        CurrentTransaction = acTransaction;

 

        BlockTableRecord acBlockTableRecord = acTransaction.GetObject(BlockIds.Peek(),

                OpenMode.ForWrite) as BlockTableRecord;                   

 

        // Fenton : you must dispose all AutoCAD objects before

        // this function goes out of scope, use using. Otherwise those objects will be disposed by the GC on a worker thread, which will most likely crash AutoCAD

        using (Region acRegion = GetProfileRegion(profile))

        {

          using (Polyline3d acPath = GetExtrusionPath(profile.Axis))

          {

            using (Solid3d acSolid = new Solid3d())

            {

              acSolid.SetDatabaseDefaults();                 

              acSolid.ExtrudeAlongPath(acRegion, acPath, 0);

 

              // Fenton: what does this line mean? if you are trying

              // to make a copy, think again because it won't

              //Solid3d acSlicedSolid = acSolid;

 

              // Fenton: this is better

              Solid3d acSlicedSolid = new Solid3d();

              acSlicedSolid.CopyFrom(acSolid);

 

              try

              {

                  SolidAnalyzer.GetFaceNormals(profile, acSolid);

              }

              finally

              {

                  if (acSlicedSolid != null)

                      acSlicedSolid.Color = Autodesk.AutoCAD.Colors.Color.FromColor(profile.OuterColor);

              }

 

              // Append the newly created object to model space and active transaction

              acBlockTableRecord.AppendEntity(acSlicedSolid);

              acTransaction.AddNewlyCreatedDBObject(acSlicedSolid, true);

 

              acPath.Erase();

            }

          }

        }

 

        // Save changes to database and close transaction

        acTransaction.Commit();

        AutoCADApplication.Print("Profile: " + profile.Name + " successfully constructed.");

    }

    catch (Autodesk.AutoCAD.Runtime.Exception ex)

    {

        AutoCADApplication.Print("Failed to construct profile " + profile.Name

            + "\n" + ex.Message + "\n\n" + ex.StackTrace);

        acTransaction.Abort();

    }

    finally

    {

        CurrentTransaction = null;

    } 

 

 





Fenton Webb

Developer Technical Services

Autodesk Developer Network


ADN Support Specialist
352 Posts
27 Kudos
Registered: ‎07-24-2007
Post 5 of 7

Re: Crash when Transaction takes too long

07-30-2012 04:30 PM in reply to: fenton.webb

I also just posted this for you guys...

 

http://adndevblog.typepad.com/autocad/2012/07/forcing-the-gc-to-run-on-the-main-thread.html





Fenton Webb

Developer Technical Services

Autodesk Developer Network


Member
4 Posts
0 Kudos
Registered: ‎07-23-2012
Post 6 of 7

Re: Crash when Transaction takes too long

07-31-2012 12:12 AM in reply to: fenton.webb

Thanks, Fenton.

The line where it says acSlicedSolid= ... was just a remain of a slicing procedure i commented out to test, sadly i forgot that line. It wasn´t intended to copy anything, it´s not a struct. Was used to determine which Solid3d to be cut because it was cut multiple times and that one was just a pointer to it.

 

Anyways, the GC won´t collect them in this case cause the objects are still referenced and using "using" doesn´t solve it either. I´ve just splitted it into multiple small transactions now and somehow it works. 


I can´t really tell why though..., thanks a lot for the help.

 

 

ADN Support Specialist
352 Posts
27 Kudos
Registered: ‎07-24-2007
Post 7 of 7

Re: Crash when Transaction takes too long

07-31-2012 09:05 AM in reply to: OrgadataPST

No problem.

 

If you post a working sample project, I'll take a look at it for you.





Fenton Webb

Developer Technical Services

Autodesk Developer Network


Post to the Community

Have questions about Autodesk products? Ask the community.

New Post