The reason why your code worked when you added
the call to Dispose(), is because you failed to add
the new RegAppTableRecord to the transaction via
AddNewlyCreatedDBObject().
When you do that, the Transaction will do the same
thing that calling Dispose() on the RegAppTableRecord
does (e.g., call Close() or Cancel() depending on if
you Commit() or Abort() the transaction, respectively).
Regarding when you must call Dispose(), it depends
on two things:
1. Is the object database resident?
2. Is the object transaction-resident?
If the answer to both questions is no, you should
call Dispose(), but you don't really need to because
when the garbage collector finalizes the object, the
wrapper will release/free the unmanaged resource.
If the object is database resident, then whether
you need to call Dispose() depends on whether the
object is transaction resident (e.g., it was returned
by calling GetObject() on the transaction, or added
to the transaction via AddNewlyCreatedDBObject()).
If the object is transaction-resident, you don't need
to call Dispose() as the transaction is responsible
for calling (and will call) either Close() or Cancel() on
the DBObject, when the transaction ends (which will
happen when you Commit(), Abort() or Dispose() it).
If a DBObject is not transaction-resident (e.g., you
used ObjectId.Open() to get the DBObject), then you
_MUST_ call either Close(), Cancel(), or Dispose() on
the object, and if you don't, it will most likely cause
AutoCAD to crash.
--
http://www.caddzone.com
AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006/2007
http://www.acadxtabs.com
"Norman Yuan" wrote in message news:5305024@discussion.autodesk.com...
Thamks for your help. I finally found the problem (very tricky) and solved
it (costing entire morning and the first hour after lunch!).
Your first instinct was right, it has something to do with registering app
name for the XData.
Here is what causes the problem: if you create a new RegAppTableRecord and
add it into RegAppTable, you have to call Dispose().
Below is the part of code I posted previously, plus the little change I
made:
Note: I added Dispose() in 3 places(marked with "!!!===") and tested the
code by commented out one or more of them in different combination, in the
end, only one matters.
//Check if "MyApp" is registered app for XData or not
using (Transaction tran =
dwg.TransactionManager.StartTransaction())
{
RegAppTable appTable =
(RegAppTable)tran.GetObject(dwg.Database.RegAppTableId, OpenMode.ForWrite);
bool exist = false;
foreach (ObjectId aID in appTable)
{
RegAppTableRecord app =
(RegAppTableRecord)tran.GetObject(aID, OpenMode.ForRead);
if (app.Name.ToUpper() == "MyApp")
{
exist = true;
break;
}
//!!!===Add Dispose() here, but has not affect
//app.Dispose();
}
//Create RegAppTableRecord, if needed
if (!exist)
{
RegAppTableRecord ct = new RegAppTableRecord();
ct.Name = "MyApp";
appTable.Add(ct);
//!!!===Added Dispose() here. Only this is required, if
you want to add XData to this application. However
//!!!===if you do registering app name and attaching
XData in seperate command, AND you close the drawing
//!!!===after restering app name, and open the drawing
again to attach XData, then you do not need this Dispose().
ct.Dispose();
}
tran.Commit();
//!!!===Add Dispose() here, but has not affect
appTable.Dispose();
}
It is just so tricky to find out the cause, and even more confusing when or
if to call object.Dispose(). In this particular case, I just do not see a
reason to call RegAppTableRecord.Dispose() after adding it into RegAppTable
object: this variable pointing to the newly created RegAppTableRecord is
going out of scope, the the RegAppTableRecord itself is handed to its
container, a RegAppTable object, why dispose it?
But anyways, after more than 5 hours struggling, I solved it. Whether it is
a .NET API implementation bug, or it is just an undocumented trick, I do not
expect there would be an explanation in future ObjectARX .NET API
documentation (if there would be such thing).
wrote in message news:5304553@discussion.autodesk.com...
Heh.... I think this may be a difference in versions of AutoCAD. I have
added XData without registering the app name before, but I am running 2005
before all the checks on XData consistency were added, it seems (there is no
method to retrieve XData by app. name, for instance).
I have one more suggestion. If you are wondering about the internal state of
AutoCAD after executing your command, you can use the ARXDBG utility. This
is an old program that was originally a ObjectARX sample that
I have compiled. It is attached.