Author Topic: How to get Entities in a Block.  (Read 18485 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: How to get Entities in a Block.
« Reply #30 on: February 10, 2012, 02:03:49 AM »
Master, are you TonyT?  cause if you are, you could make objects dispose just by thinking it. Only two people in the world could do this, TT and Chuck Norris   ^-^   

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to get Entities in a Block.
« Reply #31 on: February 10, 2012, 03:36:39 AM »

 ^-^
 :lmao:


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.

TheMaster

  • Guest
Re: How to get Entities in a Block.
« Reply #32 on: February 13, 2012, 04:08:53 PM »
I think you got lost  :lol:

I get that items such as acutPrintf are not thread safe. it's not even close to what I am taking about.


If you get that, why did you post an example that uses MessageBox.Show(),
which fails because that API and/or other AutoCAD code that gets called
as a result of calling that API can't run on the GC's thread ?

I think you messed-up :lol: because my trace API shows the message
when the finalizer runs at the next GC, but your sample shows nothing,
and from that, you are implying what?  That DeleteUnmanagedObject()
is not getting called?

Sorry, but you're mistaken.

Quote

I am talking about the "lifetime" of an underlying unmanaged object, when wrapped in a class such as disposableWapper. 


That's not what I'm talking about. I'm talking about your sample that
calls MessageBox.Show() and the point you were trying to make with
it :lol:

Quote

My goal here is not to argue with you, it's to pass on the little knowledge i have gained from writing literally thousands of wrappers for .NET : ) . 


You mean you're not playing games here?  If not, then why don't you
just state what happens when your sample runs, and what should or
should not happen?

Cheers

Jeff H

  • Needs a day job
  • Posts: 6150
Re: How to get Entities in a Block.
« Reply #33 on: February 13, 2012, 04:22:01 PM »
Guys,

I am sitting here and reading through the posts and learning a lot. Thanks for sharing your knowledge with every one.

Jeff,

Thanks for the code sample it worked like a charm but I have one issue, when i get the entities from the BlockTableRecord there is no XData in those entities, does this goes back to that cloning issue again or am I doing something wrong.
Are you after Xdata attached to the BlockReference?
eNotEnoughBeer & TheMaster please do not mind us and keep your disscusion  going.
Thanks.
 

Jeff H

  • Needs a day job
  • Posts: 6150
Re: How to get Entities in a Block.
« Reply #34 on: February 28, 2012, 04:24:36 PM »
Am I the only who sees the message box everytime?
 
Attached is a little something threw together quickly for messing around with being notified when an object's finalizer is called.
 
Sorry for the 3rd grade mentality but unless dispose explicitly called the messagebox shows up in the background being called from the GC's thread so I added a FartNotifier that plays a different fart sound for Finalize, Dispose, and DeleteUnmanaged Object. Was a little easier and more amusing for me.
 
 
And I guess since DisposableWrapper's DeleteUnmanagedObject is abstract it is hard or impossible to know what implementation will be used. DBPoint uses DBObjects implementation but would be nice from our point view if they all acted the same. 
 
 
 
 

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to get Entities in a Block.
« Reply #35 on: February 28, 2012, 04:35:17 PM »
< ... > so I added a FartNotifier that plays a different fart sound for Finalize, Dispose, and DeleteUnmanaged Object. Was a little easier and more amusing for me.
 < ... >

:) I really enjoy how unique some people are !!
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: How to get Entities in a Block.
« Reply #36 on: February 28, 2012, 05:42:01 PM »
< ... > so I added a FartNotifier that plays a different fart sound for Finalize, Dispose, and DeleteUnmanaged Object. Was a little easier and more amusing for me.
 < ... >

 :) I really enjoy how unique some people are !!
Unique/Tard same difference :)
 
For fun I guess someone could use reflection to create a new instance of each object thet derives from DisposableWrapper and see which ones crap out. Too many things to think about and I do not know about how vaild it would be.
 
Suppose to be working on something else so bad example(Not like it would good if I thought it out at all) but something like
 
Code - C#: [Select]
  1.  
  2.     public interface ILogger
  3.     {
  4.         void WriteLine(string s);
  5.     }
  6.     public class Finalizer
  7.     {
  8.         DisposableWrapper ds;
  9.         ILogger logger;
  10.         ~Finalizer()
  11.         {
  12.             logger.WriteLine(ds.GetType().Name);
  13.             ds.Dispose();
  14.         }
  15.         public Finalizer(DisposableWrapper disPos, ILogger log)
  16.         {
  17.             logger = log;
  18.             ds = disPos;
  19.         }
  20.     }
  21.     public class LogFile : ILogger
  22.     {
  23.        
  24.         StringBuilder sb;
  25.         public LogFile()
  26.         {
  27.             sb = new StringBuilder();
  28.         }
  29.         public void WriteLine(string s)
  30.         {
  31.             sb.AppendLine(s);
  32.         }
  33.         public override string ToString()
  34.         {
  35.             return sb.ToString();
  36.         }
  37.     }
  38.  

Or use the IAcadObjectLifetimeNotify interface from IFart ;)
 
« Last Edit: February 28, 2012, 05:46:28 PM by Jeff H »

kaefer

  • Guest
Re: How to get Entities in a Block.
« Reply #37 on: February 28, 2012, 06:54:56 PM »
For fun I guess someone could use reflection to create a new instance of each object thet derives from DisposableWrapper

Off on a tangent: How easy do you think is that done in a reliable manner? You'll start with
Code - C#: [Select]
  1. IEnumerable<Type> types =
  2.             from a in AppDomain.CurrentDomain.GetAssemblies()
  3.             from t in a.GetTypes()
  4.             where typeof(DisposableWrapper).IsAssignableFrom(t)
  5.             etc.
or somesuch, only to discover that some of the assemblies holding the types you're interested in aren't even loaded yet. Unless I am missing something here, you're going to need an idea which containers you want to be looked at.
« Last Edit: February 28, 2012, 07:03:14 PM by kaefer »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: How to get Entities in a Block.
« Reply #38 on: February 28, 2012, 08:57:41 PM »
For fun I guess someone could use reflection to create a new instance of each object thet derives from DisposableWrapper
Off on a tangent: How easy do you think is that done in a reliable manner?

I have no idea was just a suggestion & reason for 
Too many things to think about and I do not know about how vaild it would be.
 

I probably should not post this as I know it is not a good idea but for a general idea maybe something for listing
 
Code - C#: [Select]
  1. [CommandMethod("ListAcDbMgdDisposableTypes")]
  2.         public void ListAcDbMgdDisposableTypes()
  3.         {
  4.             Assembly ass = Assembly.Load("acdbmgd");
  5.             foreach (AssemblyName assName in ass.GetReferencedAssemblies())
  6.             {
  7.                 Assembly.Load(assName.FullName);
  8.             }
  9.             Type[] types = ass.GetTypes();
  10.             foreach (Type typ in types)
  11.             {
  12.                 if (typ.IsSubclassOf(typeof(DisposableWrapper)))
  13.                 {
  14.                     Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n"   typ.Name);
  15.                 }
  16.             }
  17.         }
  18.  
  19.  

and for creating an instance of
 
Code - C#: [Select]
  1.  
  2.   [CommandMethod("GetAcdbmgdTypes")]
  3.         public void GetAcdbmgdTypes()
  4.         {
  5.             Assembly ass = Assembly.Load("acdbmgd");
  6.             foreach (AssemblyName assName in ass.GetReferencedAssemblies())
  7.             {
  8.                 Assembly.Load(assName.FullName);
  9.             }
  10.             Type[] types = ass.GetTypes();
  11.             foreach (Type typ in types)
  12.             {
  13.                 if (typ.IsSubclassOf(typeof(DisposableWrapper)))
  14.                 {                    
  15.                     Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n"   typ.Name);
  16.                     if ((!typ.IsAbstract) && (typ.GetConstructor(Type.EmptyTypes) != null))
  17.                     {
  18.                         try
  19.                         {
  20.                             object o = Activator.CreateInstance(typ);
  21.                             DisposableWrapper d = (DisposableWrapper)o;
  22.                             Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("    ---Disposing"   typ.Name);
  23.                             d.Dispose();
  24.                         }
  25.                         catch { }
  26.  
  27.                     }
  28.  
  29.                 }    
  30.                                
  31.             }        
  32.         }
  33.  
  34.  

 

kaefer

  • Guest
Re: How to get Entities in a Block.
« Reply #39 on: February 29, 2012, 03:13:35 AM »
I probably should not post this as I know it is not a good idea but for a general idea maybe something for listing
 
Code - C#: [Select]
  1. [CommandMethod("ListAcDbMgdDisposableTypes")]
  2.         public void ListAcDbMgdDisposableTypes()
  3.         {
  4.             Assembly ass = Assembly.Load("acdbmgd");
  5.             foreach (AssemblyName assName in ass.GetReferencedAssemblies())
  6.             {
  7.                 Assembly.Load(assName.FullName);
  8.             }
  9.             Type[] types = ass.GetTypes();
  10.             foreach (Type typ in types)
  11.             {
  12.                 if (typ.IsSubclassOf(typeof(DisposableWrapper)))
  13.                 {
  14.                     Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n", typ.Name);
  15.                 }
  16.             }
  17.         }

Why, this looks like a good idea...

This approach should take care of lazily loaded assemblies, if there were any issues with acdbmgd at all. I've got bitten by the plethora of MEP assemblies: built-in commands using unmanaged code are happily working, only their managed wrappers hadn't made it yet.

JanetDavidson

  • Mosquito
  • Posts: 17
Re: How to get Entities in a Block.
« Reply #40 on: March 14, 2012, 07:17:18 PM »
Hello Daniel,
Thanks for waking me up . Honestly I  couldn't understand most of these discussions.(It is not English :cry:). I just ran your code , nce, when I started  autocad ,and it took about 10 seconds. Then I ran one of my commands which I am worry about,and then again ran your code  and took about 2 minutes.
I   disposed everything I could and nothing changed ,still 2 minutes. Am I doing something wrong? Or this is nature of autocad?
Nothing crahsed and the program works fine. You gentlemen  just made me worry. what is this GC class? Can somebody show me whether it is a must to use GC.Collect in a real project ? I feel I know nothing .
 Thanks for a good help here ?




example of how the garbage collector works with DBObjects... when do you see the message  :-)