AutoCAD .NET API provides the Transaction as the main mechanism to get object For Read, Write or Notify as introduced a while back. A Transaction has to be started anyway for either operation but can be Committed or Aborted depending on situations.
For writing operations, it is clear as crystal that we need to commit the transaction to flush the changes to the database. However, for reading operations, it is not so, and some people would naturally think it would be better to abort the transaction in such cases but others persist it is always good to commit transactions regardless.
Without good proofs or some concrete data, it would just confuse people and contradict with normal practices. Fortunately, it is not hard at all to sort it out with a small tiny but cool experiment. Here we go:
public static ObjectId GetLastCircle1()
{
ObjectId cirId = ObjectId.Null;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId id in btr)
{
DBObject obj = tr.GetObject(id, OpenMode.ForRead);
if (obj is Circle)
cirId = obj.ObjectId;
}
tr.Commit();
}
return cirId;
}
public static ObjectId GetLastCircle3()
{
ObjectId cirId = ObjectId.Null;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
foreach (ObjectId id in btr)
{
DBObject obj = tr.GetObject(id, OpenMode.ForRead);
if (obj is Circle)
cirId = obj.ObjectId;
}
//tr.Commit();
}
return cirId;
}
[CommandMethod("ReadAndCommit")]
public static void ReadAndCommit_Method()
{
Editor ed = AcadApplication.DocumentManager.MdiActiveDocument.Editor;
DateTime begin = DateTime.Now;
GetLastCircle1();
TimeSpan elapsed = DateTime.Now.Subtract(begin);
ed.WriteMessage("Time elapsed in ReadAndCommit: {0}\n", elapsed.TotalMilliseconds);
}
[CommandMethod("ReadButNotCommit")]
public static void ReadButNotCommit_Method()
{
Editor ed = AcadApplication.DocumentManager.MdiActiveDocument.Editor;
DateTime begin = DateTime.Now;
GetLastCircle3();
TimeSpan elapsed = DateTime.Now.Subtract(begin);
ed.WriteMessage("Time elapsed in ReadButNotCommit: {0}\n", elapsed.TotalMilliseconds);
}
As can be seen, we reused the GetLastCircle1() help method as introduced before and modified it a bit to create another method doing the same thing but not committing the transaction. We also adjusted the two test commands as introduced there to suit our needs here.
It is time now to launch AutoCAD, create some circles, and run the two commands:
Command: CreateCircles1
Time elapsed in CreateCircles1: 374.4006
Command: CREATECIRCLES2
Time elapsed in CreateCircles2: 639.6011
Command: ReadAndCommit
Time elapsed in ReadAndCommit: 390.0007
Command: ReadButNotCommit
Time elapsed in ReadButNotCommit: 702.0012
As can be seen, it is not necessary to commit transactions for object reading access, but for performance sake, we had better commit such transactions as well. In addition, as can be seen again from the output, it took about twice long for the second command to get the same work done. It is clear now that committing transactions is more efficient than aborting them even for reading operations.
Therefore, another good practice comes out, always committing transactions after they started.
Another interesting thing we can notice as well is that reading operations took more time than writing here. It might be specific to this particular case, but not as natural as people would think about it either.
More coding tips will be created and demonstrated in the future. Please stay tuned.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Hi,
have you tested that how fast can we open entity directly from ObjectId?
I haven´t tested but in ObjectARX it is more faster way to open objects without transactions. But there is a cave too cause we have to remember to release opened objects.
Below I put simple VB.NET example code:
Public Sub Convert2DPoly()
Dim ed As Autodesk.AutoCAD.EditorInput.Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim res As PromptEntityResult = ed.GetEntity("Select 2DPolyLine: ")
If res.Status = PromptStatus.OK Then
Using ent As Entity = res.ObjectId.Open(OpenMode.ForWrite)
If ent.GetType().Name = "Polyline2d" Then
Dim poly2d As Polyline2d = Directcast(ent, Polyline2d)
Using poly As Polyline = New Polyline()
poly.ConvertFrom(poly2d, True)
End Using
End If
End Using
End If
End Sub
Cheers
Veli V.
Posted by: Veli Väisänen | 04/04/2012 at 06:01 AM
A very good point. Thanks for pointing it out. I believe Opening the Entity directly in .NET would be way faster than using transactions, the same as before in ARX.
However, I would not suggest doing so even if it apparently brings back some performance gain. First, not so .NET technology compliant. It is not safe as you pointed out, much similar to what .NET unsafe keyword indicates but without any such warnings in AutoCAD .NET.
Second, if the opened object pointer is kept somewhere along with many others for later use to save some more transaction overheads, serious problems may just occur randomly and will be very hard to trouble shoot, making .NET coding a even less pleasant experience than c++ coding. That is what we'd like to avoid in the .NET world, IMO.
If the performance is the major concern, the ObjectARX is obviously the best and only choice, I think people would agree. ARX is much more powerful and speedy if well maneuvered, otherwise nightmare. AutoCAD .NET is much easier to use but sacrifices something for sure, such as performance here and the most important Custom Object.
Posted by: Spiderinnet1 | 04/04/2012 at 06:27 PM
Your wizard is so great!
Can I translate it into Chinese version?
Posted by: CSharpBird | 04/14/2012 at 01:52 PM
How? May I know?
Posted by: Spiderinnet1 | 04/14/2012 at 08:25 PM
Can I Email you?
My Email is csharpbird@gmail.com
Posted by: CSharpBird | 04/14/2012 at 10:59 PM
We can open discuss it if u don't mind.
Posted by: Spiderinnet1 | 04/15/2012 at 07:56 AM
Thanks for your reply.
I'm writing a book on AutoCAD .NET programming. The following url is the first edition of this book:
http://product.dangdang.com/product.aspx?product_id=20154690
Can I introduce your wizard in the book?
Posted by: CSharpBird | 04/16/2012 at 02:26 PM
The book looks nice. I think you are working on the second edition.
Yes, you can surely introduce the AutoCAD .NET Addin Wizard (AcadNetAddinWizard) in your book. You can even package the wizard into the CD if you provide one along with the book.
Let me know when you are planning to roll out the CD and the new edition. It seems better to provide you a well tested and more reliable build by that moment even if the wizard is still not final for this version.
Posted by: Spiderinnet1 | 04/16/2012 at 07:16 PM
Thanks a lot! I will put AcadNetAddinWizard into the book's CD.
The book's second edition will be wriiten by C#.
It is very appreciated that you can provide a new edition of AcadNetAddinWizard.
Posted by: CSharpBird | 04/17/2012 at 04:12 AM
By the way, it seems that the bottom line of the "Command Method" dialog cannot be seen.
The following picture show you the problem:
http://objectarx.net/uc_server/data/problem.jpg
Posted by: CSharpBird | 04/17/2012 at 04:24 AM
No problem.
In terms of the problem, I cannot access to the picture. Maybe you should make it public.
Posted by: Spiderinnet1 | 04/17/2012 at 06:37 AM
Try this:
http://www.objectarx.net/uc_server/data/problem.jpg
or:
http://www.flickr.com/photos/21634206@N03/7087398377/
Posted by: CSharpBird | 04/17/2012 at 12:10 PM
Saw the behavior this time. Thanks for posting the picture.
Obviously your Visual Studio uses a different default font and size (taller and wider) than mine. I am seeing how this kind of issues could be got rid of. Will get you updated if finding something. Meanwhile, if you have any ideas, please feel free to post comments again.
Posted by: Spiderinnet1 | 04/17/2012 at 03:20 PM
I found the following problem:
1.The assembly cannot autorun even if I set "Run it when AutoCAD is launched from inside the debugger" to True.
2.The lisp file cannot recognize non-English characters(for me:Chinese),and it will replace them with "?" characters.
Posted by: CSharpBird | 04/18/2012 at 01:04 AM
Oh, the wizard does not take that in to account. I will look into it and get back to you soon.
Posted by: Spiderinnet1 | 04/18/2012 at 03:31 AM
The Command Method page of the wizard has been re-layouted, so the last option could be seen on your OS and VS, I believe.
The dwg file name unicode issue has been addressed too. A new build will be posted soon after some more testing.
Posted by: Spiderinnet1 | 04/23/2012 at 05:26 AM
Nice Work!
When will the new edition be available?
Posted by: CSharpBird | 04/23/2012 at 11:32 PM
In one more day or two. I am cleaning up something further.
Posted by: Spiderinnet1 | 04/24/2012 at 04:04 AM
A new build has been posted to the same URL. See if it works better this time and welcome any feedback.
Posted by: Spiderinnet1 | 04/25/2012 at 10:02 PM
Thanks.
I will try it.
Posted by: CSharpBird | 04/25/2012 at 11:08 PM
The problems has all been solved.
Thanks for you hard work!
Posted by: CSharpBird | 04/25/2012 at 11:14 PM
No problem.
Posted by: Spiderinnet1 | 04/26/2012 at 02:01 AM
Hi,spiderinnet
My book will be published in next month. Will you publish a new edition of this wizard?
Posted by: CSharpBird | 05/22/2012 at 11:16 AM
Glad to hear about it.
AcadNetAddinWizard does not have an update plan for new features right now except for bug fixing. If any new issues spotted, please fee free to let us know.
Posted by: Spiderinnet1 | 05/22/2012 at 05:55 PM