I haven't investigated why AutoCAD crashes if you Dispose() the
DBObjectCollection. It could be a bug.
Regardless of that, the fact is that a DBObjectCollection does not have to
be disposed, but the DBObjects it contains *may* need to be disposed
determinstically, depending on the rules for disposing DBObjects. IOW,
depending on whether they are database-resident or transaction-resident.
In other words, there's nothing special about a DBObjectCollection as it
relates to disposition of the elements it contains and in that regards, a
DBObjectCollection behaves no differently than a List.
A DBObject must be disposed deterministically, if any of the following are
true:
1. The DBObject is not database-resident, typically these are instances
of DBObjects that were created via their new() constructor and have not been
appended to a database. There are a number of APIs that create and return
one or more new objects that are not database-resident (they leave it up to
to add them to a database if you chose). An example is the Entity's
Explode() method, which requires you to pass it a DBObjectCollection, to
which it adds the new entities it creates by exploding the object the method
is invoked on.
2. The DBObject is not transaction-resident (e.g., acquired via the
ObjectId.Open() method, which opens objects directly rather than in a
transaction). ObjectId.Open is marked as 'advanced', and should only be used
in very specialized cases (e.g., where performance is critical).
ObjectId.Open is the managed counterpart of the acdbOpenAcDbObject() native
API. In the case of non-transaction-resident DBObjects, calling Dispose() on
one always results in a call to the DBObject's Close() method, which *must*
happen if you don't want a failure. Alternately, you can explicitly call
either the Close() or Cancel() method on a non-transaction-resident
DBObject, and once you've done so, you no longer need to call Dispose().
DBObjects that are passed in the arguments of event handlers should never be
disposed.
The ObjectId.GetObject() method is really just another way of calling
GetObject() on the top transaction (hence, it requires an active
transaction), so the resulting object is always transaction-resident.
In the case of your code, GetAllObjects() returns all objects that are open
in all active transactions, which of course, means that all returned objects
should be transaction-resident and hence, do not need to be
deterministically disposed.
I agree completely with your frustration over the Dispose() enigma, because
it certainly is confusing, and IMO, needlessly so.
That's a result of what I believe is a less-than-optimal API design, where
just about everything that wraps a native API is a descendent of a type
called 'DisposableWrapper' (the class that implements IDisposable).
And as you've noted, in some cases the wrappers do not need to be
determinstically disposed, and in a few cases, must *never* be.
The bottom line here insofar as DBObjectCollection goes, is that you do not
need to be concerned with disposing a DBObjectCollection, but you must be
concerned with disposing the DObjects it contains (because the containing
DBObjectCollection does not do that for you), according to the
aforementioned guidelines. In this specific case, since all of the objects
in the DBObjectCollection are transaction-resident, you don't have to
dispose them, and obviously there is a problem if you do call Dispose() on
the DBObjectCollection, but I haven't looked at that so can't tell you much
about it.
Additionally, whenever you do dispose of the objects in a
DBObjectCollection, you should probably also call its Clear() method before
you finish using the collection.
--
http://www.caddzone.com
AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com
Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm
"James Allen" wrote in message
news:6160576@discussion.autodesk.com...
And here is the attachment, zipped and hopefully not mangled this time.
James
James Allen wrote:
> I'm fed up with this. Maybe I just haven't got it yet, but I think this
> is ridiculous. Can we please nail down exactly when to or not to
> Dispose().
>
> I've studied, read carefully word for word, and then revisited multiple
> times numerous opinions on this, especially those posted by Kean and
> Tony. Still I'm being plagued by problems which I believe boil down to
> Dispose().
>
> Here's what I've got:
> 1. Not DBObject - [1] Either
> 2. DBObject, no Database - [1] Yes, but [2] Either (Yes Advised)
> 3. DBObject, in Database, in Transaction - [1,3] Either
> 4. DBObject, in Database, no Transaction - [2,3] Yes
> 5. With "Deterministic Destructor Semantics"
> (DocumentLock, Transaction, DBObject) - [3] Yes
> 6. Created Object - [3] Yes
> 7. Returned Object - [3] Depends
> 8. ResultBuffer - [3] Either, but comments at [4] (Wyatt, Kean, 03,
> 04Apr07) maybe Yes
> 9. Aggregates, collection members, no constructor (Document) - [5] No
> 10. DBObjectCollection - [6] Either, but [7] Yes
> 11. Anything referencing other DBObjects in Database
> (DBObjectCollection) - speculation on [7] Yes
>
> [1]
> http://through-the-interface.typepad.com/through_the_interface/2008/06/cleaning-up-aft.html
> [2]
> http://discussion.autodesk.com/forums/thread.jspa?messageID=5902684ᅜ
> [3]
> http://discussion.autodesk.com/forums/message.jspa?messageID=5736485#5736485
> [4]
> http://through-the-interface.typepad.com/through_the_interface/2007/04/adding_xdata_to.html
> [5]
> http://discussion.autodesk.com/forums/message.jspa?messageID=5101329#5101329
> [6]
> http://discussion.autodesk.com/forums/thread.jspa?messageID=6132777鐩
> [7] Attached code yields "FATAL ERROR: Unhandled Access Violation
> Reading 0x7ed33331c Exception
> at 62064bb3h" or similar on closing AutoCAD. Uncomment Dispose() and no
> error. Is this not a Dispose() problem and there is something else I'm
> missing? I stumbled onto it trying to track down something else.
> WinXP, Acad2008, VSE2005.
>
> What am I still missing? Please enlighten me.
>
> Thanks,
>
> --
> James Allen
> Malicoat-Winslow Engineers, P.C.
> Columbia, MO
>