Author Topic: Fenton Webb's advice re "To dispose or not to dispose"  (Read 75528 times)

0 Members and 2 Guests are viewing this topic.

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #75 on: August 09, 2012, 11:46:17 PM »

I refuse to entertain the sort of kludgery that the typical LISP die-hard is willing to resort to in order to justify their existence. :grin:

As far as Fenton goes, give me access to the same things he has access to and I'll clean his clock. :grin:

Best thread in ages. I'm not in their league so I can't form an intelligent opinion but I love the debate/discussion.

What great timing! An Olympic Code Writing event? USA vs Russia vs Great Britain vs India vs ?? That would be fantastic and SO educational. Of course the results would be debatable which makes it all the more interesting.

So where were we? . . . . oh yeah . . . gauntlet thrown.
Please continue.
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #76 on: August 10, 2012, 02:44:05 AM »
My friend Alexander Rivilis said your name behind the nickname TT. I hasten to say, I really respect you for your contribution to programming. Indeed, the competition will be hot and fun!

ps. Yes, I will publish here all the sources. I hope you will too...

Thanks.

But, if your intention is to use AutoCAD Core Console as a form of parallel execution, I would not consider that to be a legitimate solution (that is technically multi-processing rather than multi-threading).

Since the LISP garbage collector is not capable of dealing with multiple threads, even if you did find some way to get an entry point on another thread, it would certainly fail given the appropriate stress-testing.

If you recall the story, the original lisp no one was interested, until the show concurrent execution in a network of computers. After that, two years later, was written specification language and the language was fully certified for any use, including defense.

You know Lisp. You should be clear that Lisp is the language of the lists. The meaning of the program - sequential passage through the list items and their computation. But in the lists may be other lists of data and programs. Each calculation can be performed at its core (thread or processor or computer).


I've noticed that many AutoLISP die-hard enthusiasts, when confronted with the usual criticism about their favorite programming language, often resort to the tactic of confusing AutoLISP with ANSI Common LISP or various other full-featured LISP development tools. What you say about the latter is true - many of them can compile to native code that can run as fast or faster than code compiled from C/C++.

But, please do not confuse those development tools with AutoLISP, which is lame by comparison.


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8718
  • AKA Daniel
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #77 on: August 10, 2012, 02:53:20 AM »
Way to go TT, now your implying lisp hacks may out perform native hacks  :lol:

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #78 on: August 10, 2012, 03:12:26 AM »
If you were tasked for writing code to just run in the CoreConsole and knew it would never be used with acad.exe(I know does not make much sense) and normally would have a coreConsoles running for each core at the same time would that be good candidate for setting gcConcurrent flag and not worrying about disposing everything?

With relatively-full CPU utilization (all cores that is), and running multiple ACC's, you are generally not waiting for things to happen, so I don't think it would matter that much. The idea behind allowing the GC to run concurrently in AutoCAD is because the typical AutoCAD workflow involves one interactive process that's not making good use of multiple processors, and so there is likely one or more under-utilized processors that can do the garbage collection without impacting AutoCAD use.


ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #79 on: August 10, 2012, 03:13:50 AM »
I've noticed that many AutoLISP die-hard enthusiasts, when confronted with the usual criticism about their favorite programming language, often resort to the tactic of confusing AutoLISP with ANSI Common LISP or various other full-featured LISP development tools. What you say about the latter is true - many of them can compile to native code that can run as fast or faster than code compiled from C/C++.

But, please do not confuse those development tools with AutoLISP, which is lame by comparison.

I do not understand ...
You have refused to match, but stubbornly continue to claim that I want you to cheat and use other languages.
You have all the languages except AutoLISP. I only lisp. Together, we can use all the features of AutoCAD latest version. - These are the conditions.

My opinion is that the large-scale problems, the implementation of complex algorithms in LISP, is much easier and faster. During the allotted time, I can easily develop a full-fledged work of eight of computing power while working at a result. Includes all necessary synchronization and data transfer. The result is supposed to be a fairly simple and straightforward. So, I declare that in other languages​​, such a task is very difficult to implement! I think the difference in the elaboration of the algorithm is completely exclude the quality of the code in other languages ​​and Lisp have a chance to win...

ps. The only thing I dislike about selected to match the problem - my best algorithms for the program has long been known and copied in other languages​​...

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #80 on: August 10, 2012, 03:24:37 AM »
in my defense I say - Lisp is really slower than other languages ​​used in AutoCAD. But Lisp algorithmic language and it can be quickly and easily develop complex algorithms.
In other words - I am sure that over the same time, Lisp and other languages ​​like C, Lisp is a high quality program.

According to my estimates, quality code in LISP and ARX - the difference:
2000 - 4000% for the input - output
9% - 140% for mathematics and logic

about any hundreds of times one can not speak!  :kewl:

fentonwebb

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #81 on: August 11, 2012, 01:26:26 AM »
Hey guys

a couple of things...

First of all... I posted a new Performance post here http://adndevblog.typepad.com/autocad/2012/08/the-right-tools-for-the-job-autocad-part-5.html

Second of all, if you are in any way confused when to Dispose or not, I have an idea - how about you do *exactly* what TT said not to do (right at the beginning of this post) Dispose absolutely everything!!!! I'm not disrespecting you TT, I'm just running with an idea...

I figure the worst that can happen is your code will cause AutoCAD to simply crash - the good thing though about this approach is, if it crashes it should crash right there and then! I think that is much better than crashing some random place and time when the GC decides kicks in. Also, if it does crash then just tell me! That's because it's a bug, and I'll get it fixed so that it doesn't crash - how does that sound?




gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #82 on: August 11, 2012, 01:36:19 PM »
Quote
Second of all, if you are in any way confused when to Dispose or not, I have an idea - how about you do *exactly* what TT said not to do (right at the beginning of this post) Dispose absolutely everything!!!!

You're jocking Fenton !... :-o

I think what I and others newbies are waiting for is a definitive and clear explaination of:
- what absolutely needs to be explictely disposed,
- what doesn't need to be disposed,
- what is a safer practice to dispose to prevent unexcepted situations(i.e. an exception occurs).
I think this could be done with simple and clear samples provided in the AutoCAD .NET Developper's Guide, ObjectARX docs or any other Autodesk publications.

Here's a sample example of what I mean.
It covers nearly all I think I finally understood about this since I started AutoCAD .NET self-teaching.

Code - C#: [Select]
  1.         public void ExtrudePline()
  2.         {
  3.             // Never dispose Document nor Document.Editor
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.  
  7.             // Never dispose Database when the drawing is opened in the Editor
  8.             // On the other hand, always dispose Database created with the constructor, i.e. new Database()
  9.             Database db = doc.Database;
  10.  
  11.             // Always dispose DocumentLock
  12.             using (doc.LockDocument())
  13.             // Always dispose Transaction
  14.             using (Transaction tr = db.TransactionManager.StartTransaction())
  15.             {
  16.                 // No need to dispose a DBObject opened from a transaction
  17.                 BlockTableRecord currentSpace =
  18.                     (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  19.  
  20.                 // Always dispose a new DBObject which may not be added to the database
  21.                 using (Polyline pline = new Polyline())
  22.                 {
  23.                     pline.AddVertexAt(0, Point2d.Origin, 0.0, 0.0, 0.0);
  24.                     pline.AddVertexAt(1, new Point2d(10.0, 0.0), 0.0, 0.0, 0.0);
  25.                     pline.AddVertexAt(2, new Point2d(10.0, 10.0), 1.0, 0.0, 0.0);
  26.                     pline.AddVertexAt(3, new Point2d(0.0, 10.0), 0.0, 0.0, 0.0);
  27.                     pline.Closed = true;
  28.  
  29.                     // Dispose DBObjectCollection in case there're some objects left
  30.                     // for which no managed wrapper have been created
  31.                     using (DBObjectCollection plineCollection = new DBObjectCollection())
  32.                     {
  33.                         plineCollection.Add(pline);
  34.  
  35.                         // Dispose DBObjectCollection in case there're some objects left
  36.                         // for which no managed wrapper have been created
  37.                         using (DBObjectCollection regionCollection =
  38.                             Region.CreateFromCurves(plineCollection))
  39.                         {
  40.                             // Always dispose an object contained in a DBObjectCollection
  41.                             // for which a managed wrapper is created and isn't added to the database
  42.                             using (Region region = (Region)regionCollection[0])
  43.                             {
  44.                                 // Use Dispose to insure the new DBObject will be disposed
  45.                                 // if an exception occurs before it is added to the Database
  46.                                 using (Solid3d solid = new Solid3d())
  47.                                 {
  48.                                     solid.Extrude(region, 30.0, 0.0);
  49.                                     currentSpace.AppendEntity(solid);
  50.                                     tr.AddNewlyCreatedDBObject(solid, true);
  51.                                 }
  52.                             }
  53.                         }
  54.                     }
  55.                     if ((short)Application.GetSystemVariable("DELOBJ") == 0)
  56.                     {
  57.                         currentSpace.AppendEntity(pline);
  58.                         tr.AddNewlyCreatedDBObject(pline, true);
  59.                     }
  60.                 }
  61.                 tr.Commit();
  62.             }
  63.         }

Code - vb.net: [Select]
  1.         Public Sub ExtrudePline()
  2.             ' Never dispose Document nor Document.Editor
  3.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  4.             Dim ed As Editor = doc.Editor
  5.  
  6.             ' Never dispose Database when the drawing is opened in the Editor
  7.             ' On the other hand, always dispose Database created with the constructor (i.e. New Database())
  8.             Dim db As Database = doc.Database
  9.  
  10.             ' Always dispose DocumentLock
  11.             Using doc.LockDocument()
  12.  
  13.                 ' Always dispose Transaction
  14.                 Using tr As Transaction = db.TransactionManager.StartTransaction()
  15.  
  16.                     ' No need to dispose a DBObject opened from a transaction
  17.                     Dim currentSpace As BlockTableRecord = _
  18.                         DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
  19.  
  20.                     ' Always dispose a new DBObject which may not be added to the database
  21.                     Using pline As New Polyline()
  22.                         pline.AddVertexAt(0, Point2d.Origin, 0.0, 0.0, 0.0)
  23.                         pline.AddVertexAt(1, New Point2d(10.0, 0.0), 0.0, 0.0, 0.0)
  24.                         pline.AddVertexAt(2, New Point2d(10.0, 10.0), 1.0, 0.0, 0.0)
  25.                         pline.AddVertexAt(3, New Point2d(0.0, 10.0), 0.0, 0.0, 0.0)
  26.                         pline.Closed = True
  27.  
  28.                         ' Dispose DBObjectCollection in case there're some objects left
  29.                         ' for which no managed wrapper have been created
  30.                         Using plineCollection As New DBObjectCollection()
  31.                             plineCollection.Add(pline)
  32.  
  33.                             ' Dispose DBObjectCollection in case there're some objects left
  34.                             ' for which no managed wrapper have been created
  35.                             Using regionCollection As DBObjectCollection = _
  36.                                 Region.CreateFromCurves(plineCollection)
  37.  
  38.                                 ' Always dispose an object contained in a DBObjectCollection
  39.                                 ' for which a managed wrapper is created and isn't added to the database
  40.                                 Using region As Region = DirectCast(regionCollection(0), Region)
  41.  
  42.                                     ' Use Dispose to insure the new DBObject will be disposed
  43.                                     ' if an exception occurs before it is added to the Database
  44.                                     Using solid As New Solid3d()
  45.                                         solid.Extrude(region, 30.0, 0.0)
  46.                                         currentSpace.AppendEntity(solid)
  47.                                         tr.AddNewlyCreatedDBObject(solid, True)
  48.                                     End Using
  49.                                 End Using
  50.                             End Using
  51.                         End Using
  52.                         If CShort(Application.GetSystemVariable("DELOBJ")) = 0 Then
  53.                             currentSpace.AppendEntity(pline)
  54.                             tr.AddNewlyCreatedDBObject(pline, True)
  55.                         End If
  56.                     End Using
  57.                     tr.Commit()
  58.                 End Using
  59.             End Using
  60.         End Sub
« Last Edit: August 12, 2012, 09:58:41 AM by gile »
Speaking English as a French Frog

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #83 on: August 11, 2012, 08:54:07 PM »

First of all... I posted a new Performance post here http://adndevblog.typepad.com/autocad/2012/08/the-right-tools-for-the-job-autocad-part-5.html

< .. >

Fenton, The DBObject class in DatabaseServices namespace thinks that
Quote
Autodesk.AutoCAD.DatabaseServices.DBObject.Close()' is obsolete: 'Use Transaction instead'   


Autodesk.AutoCAD.DatabaseServices.ObjectId.Open(Autodesk.AutoCAD.DatabaseServices.OpenMode)' is obsolete: 'For advanced use only. Use GetObject instead'   

It seems that your personal preference to use Open/Close is contrary to the class designer's intent.



« Last Edit: August 11, 2012, 10:35:46 PM by Kerry »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #84 on: August 11, 2012, 09:48:43 PM »
My Results using the drawings from Post Reply#31
Thanks to Jeff H for the Post.

Note that the returned value is Stopwatch.Ticks not DateTime.Ticks.( see note)

TestDrawing_150000 .dwg
Command: OPENCLOSETRANSACTION
2018 143
2012 762
2011 954
2005 563
2032 259
Command: OPENCLOSE
2202 859
2130 969
2166 854
2199 823
Command: STARTTRANSACTION
5209 462
5451 483
5339 095
5300 119
5247 409
Command: IDGETOBJECT
6594 048
6607 023
6550 874
6545 139
6486 834


This test simply Opens each entity and changes it's color to match a random number.
I imagine that most operations would reflect a similar differential.


note
http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx
Quote
In short, remember that the ticks in Stopwatch are machine/OS dependent, thus you should never count on the ration of Stopwatch ticks to seconds to be the same between two systems, and possibly even on the same system after a reboot.  Thus, you can never count on Stopwatch ticks to be the same interval as DateTime/TimeSpan ticks.

To get system-independent time, make sure to use the Stopwatch’s Elapsed or ElapsedMilliseconds properties, which already take the Stopwatch.Frequency (ticks per second) into account.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #85 on: August 11, 2012, 10:15:22 PM »

About The Transaction object in AutoCAD... The Transaction model (StartTransaction()) was invented way back when for a specific reason - transacting multiple writes on the same objects(s) and allowing layered rollbacks of these multi-write transactions.

Here’s what I recommend:
If you guys are using StartTransaction(),
and you don’t need the multiple write feature I just mentioned in the above paragraph,
simply change your StartTransaction() to StartOpenCloseTransaction()…


Is anyone able to clarify the distinction regarding transacting multiple writes on the same objects(s)

Regards
Kerry
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #86 on: August 11, 2012, 10:45:38 PM »
!... :-o

I think what I and others newbies are waiting for is a definitive and clear explaination of:
- what absolutely needs to be explictely disposed,
- what doesn't need to be disposed,
- what is a safer practice to dispose to prevent unexcepted situations(i.e. an exception occurs).
I think this could be done with simple and clear samples provided in the AutoCAD .NET Developper's Guide, ObjectARX docs or any other Autodesk publications.

< .. >



votes += mine;

Thanks gile,

Regards
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #87 on: August 11, 2012, 11:32:58 PM »
First off thanks for repling Fenton, your input is greatly appreciated
 

 
.......
Note that the returned value is Stopwatch.Ticks not DateTime.Ticks.( see note)
.......

note
http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx
Quote
In short, remember that the ticks in Stopwatch are machine/OS dependent, thus you should never count on the ration of Stopwatch ticks to seconds to be the same between two systems, and possibly even on the same system after a reboot. Thus, you can never count on Stopwatch ticks to be the same interval as DateTime/TimeSpan ticks.

To get system-independent time, make sure to use the Stopwatch’s Elapsed or ElapsedMilliseconds properties, which already take the Stopwatch.Frequency (ticks per second) into account.
Oops Thanks!
The thing that makes me face palm more than anything else is the crap I slapped together here was performing better than OpenCloseTransaction, and of course it has not been throughly tested and was just a simple test. Code not updated for stopwatch as Kerry noted. Thanks again!
Code - C#: [Select]
  1.         [CommandMethod("TurnAllEntitesRandomRollYorOwn")]
  2.         public void TurnAllEntitesRandomRollYorOwn() // This method can have any name
  3.         {
  4.             int colorIndex = ran.Next(1, 256);
  5.             Database db = HostApplicationServices.WorkingDatabase;
  6.             ObjectId msId = SymbolUtilityServices.GetBlockModelSpaceId(db);
  7.             Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
  8.             sw.Reset();
  9.             sw.Start();
  10.             using (ITransaction trx = db.StartRollYourOwnTransaction())
  11.             {
  12.                 BlockTableRecord btr = (BlockTableRecord)trx.GetObject(msId, OpenMode.ForRead, false, false);
  13.                 foreach (ObjectId id in btr)
  14.                 {
  15.                     Entity ent = (Entity)trx.GetObject(id, OpenMode.ForWrite, false, false);
  16.                     ent.ColorIndex = colorIndex;
  17.                 }
  18.  
  19.                 trx.Commit();
  20.             }
  21.             sw.Stop();
  22.             Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nRollYorOwn\n");
  23.             Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(sw.ElapsedTicks.ToString());
  24.         }
  25.  
« Last Edit: August 12, 2012, 09:03:52 AM by Jeff H »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #88 on: August 12, 2012, 12:04:04 AM »
I have code that plays a squeaker fart noise if I forget to call dispose on object(squeezing the last bit of life out of it) which goes to show you can do anything inside dispose method, and no reason to reply what an ingenious idea that is as it is already understood.
 
So to look at what happens when a line is disposed I can follow the different paths except for one part in DeleteUnmanagedObject.
Where it checks if its ObjectId is null and if so then if the DBObject is Not null I am not sure what that does?
calli
Code - C#: [Select]
  1.  
  2.  
  3.         ////    DBObject
  4.         protected unsafe override void DeleteUnmanagedObject()
  5.         {
  6.             AcDbObject* impObj = this.GetImpObj();
  7.             AcDbObjectId acDbObjectId;
  8.             if (((*<Module>.AcDbObject.objectId(impObj, &acDbObjectId) == 0L) ? 1 : 0) != 0)
  9.             {
  10.                 if (impObj != null)
  11.                 {
  12.                     object arg_24_0 = calli(System.Void* modopt(System.Runtime.CompilerServices.CallConvCdecl)(System.IntPtr,System.UInt32), impObj, 1, *(*(long*)impObj));
  13.                 }
  14.             }
  15.             else
  16.             {
  17.                 int num = (int)<Module>.AcDbObject.close(this.GetImpObj());
  18.                 if (num != 0)
  19.                 {
  20.                     throw new Autodesk.AutoCAD.Runtime.Exception((ErrorStatus)num);
  21.                 }
  22.             }
  23.         }
  24.  
  25.  
  26.  
  27.  

I think I got all the methods used for a line used when Disposed is called
Code - C#: [Select]
  1.  
  2.         ////    DisposableWrapper
  3.         public sealed override void Dispose()
  4.         {
  5.             this.Dispose(true);
  6.             GC.SuppressFinalize(this);
  7.         }
  8.  
  9.  
  10.         ////    DisposableWrapper
  11.         protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag)
  12.         {
  13.             if (flag)
  14.             {
  15.                 this.~DisposableWrapper();
  16.             }
  17.             else
  18.             {
  19.                 try
  20.                 {
  21.                     this.!DisposableWrapper();
  22.                 }
  23.                 finally
  24.                 {
  25.                     base.Finalize();
  26.                 }
  27.             }
  28.         }
  29.  
  30.         ////    DisposableWrapper
  31.         private void ~DisposableWrapper()
  32.         {
  33.             this.!DisposableWrapper();
  34.         }
  35.  
  36.         ////    DisposableWrapper
  37.         private void !DisposableWrapper()
  38.         {
  39.             if (this.m_bAutoDelete && this.m_imp != IntPtr.Zero)
  40.             {
  41.                 this.DeleteUnmanagedObject();
  42.             }
  43.             this.Detach();
  44.         }
  45.  
  46.  
  47.  
  48.         ////    DisposableWrapper
  49.         internal void Detach()
  50.         {
  51.             this.m_imp = IntPtr.Zero;
  52.             if (this.m_bAutoDelete)
  53.             {
  54.                 GC.SuppressFinalize(this);
  55.             }
  56.             this.m_bAutoDelete = false;
  57.             GC.KeepAlive(this);
  58.         }
  59.  
  60.         ////    DBObject
  61.         protected override void Dispose([MarshalAs(UnmanagedType.U1)] bool flag)
  62.         {
  63.             if (flag)
  64.             {
  65.                 try
  66.                 {
  67.                     return;
  68.                 }
  69.                 finally
  70.                 {
  71.                     base.Dispose(true);
  72.                 }
  73.             }
  74.             try
  75.             {
  76.                 this.!DBObject();
  77.             }
  78.             finally
  79.             {
  80.                 base.Dispose(false);
  81.             }
  82.         }
  83.  
  84.         ////    DBObject
  85.         protected unsafe override void DeleteUnmanagedObject()
  86.         {
  87.             AcDbObject* impObj = this.GetImpObj();
  88.             AcDbObjectId acDbObjectId;
  89.             if (((*<Module>.AcDbObject.objectId(impObj, &acDbObjectId) == 0L) ? 1 : 0) != 0)
  90.             {
  91.                 if (impObj != null)
  92.                 {
  93.                     object arg_24_0 = calli(System.Void* modopt(System.Runtime.CompilerServices.CallConvCdecl)(System.IntPtr,System.UInt32), impObj, 1, *(*(long*)impObj));
  94.                 }
  95.             }
  96.             else
  97.             {
  98.                 int num = (int)<Module>.AcDbObject.close(this.GetImpObj());
  99.                 if (num != 0)
  100.                 {
  101.                     throw new Autodesk.AutoCAD.Runtime.Exception((ErrorStatus)num);
  102.                 }
  103.             }
  104.         }
  105.  
  106.         ////    DBObject
  107.         public void Close()
  108.         {
  109.             int num = (int)<Module>.AcDbObject.close(this.GetImpObj());
  110.             if (num != 0)
  111.             {
  112.                 throw new Autodesk.AutoCAD.Runtime.Exception((ErrorStatus)num);
  113.             }
  114.             base.Detach();
  115.         }
  116.  

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #89 on: August 12, 2012, 12:11:18 AM »
I have code that plays a squeaker fart noise if I forget to call dispose on object(squeezing the last bit of life out of it) which goes to show you can do anything inside dispose method, and no reason to reply what an ingenious idea that is as it is already understood.
 
So to look at what happens when a line is disposed I can follow the different paths except for one part in DeleteUnmanagedObject.
Where it checks if its ObjectId is null and if so then if the DBObject is Not null I am not sure what that does?
calli


First it checks to see if the ObjectId is null, which means the object is not database-resident.  If the object is not database-resident then it deletes the wrapped AcDbObject.

If the object is database-resident then it calls AcDbObject::close(), which doesn't actually close objects that are transaction-resident.
« Last Edit: August 12, 2012, 12:52:26 AM by TT »