TheSwamp

Code Red => .NET => Topic started by: Kerry on April 25, 2012, 03:52:24 AM

Title: Something I wish I'd known a couple of years ago ..
Post by: Kerry on April 25, 2012, 03:52:24 AM
Quote from: http://adndevblog.typepad.com/autocad/2012/04/use-transaction-from-a-sub-function.html
Use transaction from a sub function
By Adam Nagy
 
If you start a transaction inside your main function, then you do not need to create another one (a sub transaction) inside your sub function, you do not even need to pass the transaction to the sub function, you can simply use ObjectId.GetObject() instead, which will automatically use the outer transaction you started.
< .. code follows .. >
Title: Re: Something I wish I'd known a couple of years ago ..
Post by: n.yuan on April 25, 2012, 12:06:57 PM
Well, for early starters of Acad .NET API programming (Acad 2005/6), there is no ObjectId.GetObject() method, it only has obsolete method Open().

Lots of my base code was created on Acad2006 and still in use. So I have been acustomed to always use Transaction.GetObject(), even I later knew ObjectId.GetObject() was available since Acad2007 or 2008. Yes, I either start a new transaction in the sub function, or pass the top transaction to the sub functions. Just out of habit.
Title: Re: Something I wish I'd known a couple of years ago ..
Post by: It's Alive! on April 25, 2012, 08:26:09 PM
I still pass the transaction as an argument, just in case I need to add a newly created object.

BTY even though Open has the obsolete attribute, it does say 'For advanced use only', so if you're doing advanced stuff, your good to go  :-D
Title: Re: Something I wish I'd known a couple of years ago ..
Post by: TheMaster on April 26, 2012, 05:40:56 AM
Quote from: http://adndevblog.typepad.com/autocad/2012/04/use-transaction-from-a-sub-function.html
Use transaction from a sub function
By Adam Nagy
 
If you start a transaction inside your main function, then you do not need to create another one (a sub transaction) inside your sub function, you do not even need to pass the transaction to the sub function, you can simply use ObjectId.GetObject() instead, which will automatically use the outer transaction you started.
< .. code follows .. >

Most of the code I've written in recent years assumes there's an active transaction,
and uses ObjectId.GetObject(), or some extension methods I use that gets the top
transaction for adding new objects, etc. If I need to pass something, it's usually a
Database, since I can get the top/active transaction from it. A transaction has no
Database property, so if I need the Database, passing a transaction isn't terribly
useful.

Code - C#: [Select]
  1.  
  2.   public static class BlockTableRecordExtensions
  3.   {
  4.     // Append a sequence of new entities to the block
  5.     // and add to the top transaction. If an error is
  6.     // raised, all entities in the sequence will be
  7.     // disposed.
  8.    
  9.     public static ObjectIdCollection Add( this BlockTableRecord owner, IEnumerable<Entity> entities )
  10.     {
  11.       if( entities == null )
  12.         throw new ArgumentNUllException( "entities" );
  13.       Transaction trans = owner.Database.TransactionManager.TopTransaction;
  14.       if( tr == null )
  15.         throw new Autodesk.AutoCAD.Runtime.Exception( ErrorStatus.NoTransaction );
  16.       ObjectIdCollection ids = new ObjectIdCollection();
  17.       try
  18.       {
  19.         foreach( Entity ent in entities )
  20.         {
  21.           ids.Add( owner.AppendEntity( ent ) );
  22.           trans.AddNewlyCreatedDBObject( ent, true );
  23.         }
  24.       }
  25.       catch
  26.       {
  27.         entities.DisposeAll();
  28.         throw;
  29.       }
  30.       return ids;
  31.     }
  32.    
  33.     // Allows entities to be passed as parameters to the above method:
  34.    
  35.     public static ObjectIdCollection AddRange( this BlockTableRecord owner, params Entity[] entities )
  36.     {
  37.        return Add( owner, (IEnumerable<Entity>) entities );
  38.     }
  39.    
  40.     // Append a single entity and add to top transaction.
  41.    
  42.     public static ObjectId Add( this BlockTableRecord owner, Entity ent )
  43.     {
  44.       if( owner == null )
  45.         throw new ArgumentNullException( "owner" );
  46.       if( ent == null )
  47.         throw new ArgumentNullException( "ent" );
  48.       try
  49.       {
  50.         ObjectId id = owner.AppendEntity( ent );
  51.         owner.Database.TransactionManager.AddNewlyCreatedDBObject( ent, true );
  52.         return id;
  53.       }
  54.       catch
  55.       {
  56.         ent.Dispose();
  57.         throw;
  58.       }
  59.     }
  60.    
  61.     public static void DisposeAll( this IEnumerable<IDisposable> disposables )
  62.     {
  63.       foreach( IDisposable disposable in disposables )
  64.         disposable.Dispose();
  65.     }
  66.    
  67.   }
  68.  
  69.  
Title: Re: Something I wish I'd known a couple of years ago ..
Post by: Kerry on April 26, 2012, 06:43:21 AM

Thanks Tony.
I'll digest that over the weekend.

Regards
Title: Re: Something I wish I'd known a couple of years ago ..
Post by: It's Alive! on April 26, 2012, 07:17:55 AM
nice  8-)