.NET

Reply
*perry
Message 1 of 3 (141 Views)

blocktablerecord dispose - NOT

141 Views, 2 Replies
08-01-2006 02:36 PM
In the partial code listing below is a line which I call many times, and Im sure most other programmers
do as well. It comes straight out of the Adesk docs (trans.getobject...).
Problem is everytime I use it the debugger IDE tells me I "forgot" to close the record, even though
you can see that I do. Funny thing is I dont get a similar "warning" about closing the block table
which uses the same mechanism.
Is this an Acad net wrapper bug?
-----------------------------------------------------------------------------------------------
private void checkBlockDef()
{
int attCount = 0;
using (Database dBase = HostApplicationServices.WorkingDatabase)
{
Transaction trans = dBase.TransactionManager.StartTransaction(); // begin the transaction
try
{
//Now, drill into the database and obtain a reference to the BlockTable
BlockTable blkTbl = (BlockTable)trans.GetObject(dBase.BlockTableId, OpenMode.ForWrite);
BlockTableRecord blkTblRec = new BlockTableRecord();
if (blkTbl.Has("TBREVISION"))
{
//check number of attribute definitions
//See notes 1
// either of the next two lines will give the following warning in the debugger on exit
//Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.BlockTableRecord): DisposableWrapper
// blkTblRec = (BlockTableRecord)trans.GetObject(Utilities.getRevDef(dBase, trans), OpenMode.ForRead, false);
blkTblRec = (BlockTableRecord)trans.GetObject(blkTbl["TBREVISION"], OpenMode.ForRead, false);
}
trans.Commit(); //All done, no errors? Go ahead and commit!
blkTblRec.Dispose();
blkTbl.Dispose();
}
catch (System.Exception ex)
{
Utilities.Message(ex);
}
finally
{
trans.Dispose();
}
}//end using database
}
*Tony Tanzillo
Message 2 of 3 (141 Views)

Re: blocktablerecord dispose - NOT

08-01-2006 03:03 PM in reply to: *perry
>> BlockTableRecord blkTblRec = new BlockTableRecord();

Why are you creating a new instance of a BlockTableRecord,
if you're not adding a new block definition to the drawing?

That's what's causing the runtime to complain. You're creating
a new BlockTableRecord, but you don't use it.

Right after that, the variable you assigned that new instance
to is subsequently reassigned to another instance of that
same class (returned by GetObject()).

DisposableWrapper sees that your code has problems and so
it lets you know about that.

If that's exactly what appears in the Autodesk sample code,
it's quite possible that it predates the AutoCAD 2006 API,
where there were significant differences in how you handled
opening/closing of objects.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006/2007
http://www.acadxtabs.com

"perry" wrote in message news:5255514@discussion.autodesk.com...
In the partial code listing below is a line which I call many times, and Im sure most other programmers
do as well. It comes straight out of the Adesk docs (trans.getobject...).

Problem is everytime I use it the debugger IDE tells me I "forgot" to close the record, even though
you can see that I do. Funny thing is I dont get a similar "warning" about closing the block table
which uses the same mechanism.
Is this an Acad net wrapper bug?
-----------------------------------------------------------------------------------------------
private void checkBlockDef()
{
int attCount = 0;
using (Database dBase = HostApplicationServices.WorkingDatabase)
{
Transaction trans = dBase.TransactionManager.StartTransaction(); // begin the transaction
try
{
//Now, drill into the database and obtain a reference to the BlockTable
BlockTable blkTbl = (BlockTable)trans.GetObject(dBase.BlockTableId, OpenMode.ForWrite);
BlockTableRecord blkTblRec = new BlockTableRecord();
if (blkTbl.Has("TBREVISION"))
{
//check number of attribute definitions
//See notes 1
// either of the next two lines will give the following warning in the debugger on exit
//Forgot to call Dispose? (Autodesk.AutoCAD.DatabaseServices.BlockTableRecord): DisposableWrapper
// blkTblRec = (BlockTableRecord)trans.GetObject(Utilities.getRevDef(dBase, trans), OpenMode.ForRead, false);
blkTblRec = (BlockTableRecord)trans.GetObject(blkTbl["TBREVISION"], OpenMode.ForRead, false);
}
trans.Commit(); //All done, no errors? Go ahead and commit!
blkTblRec.Dispose();
blkTbl.Dispose();
}
catch (System.Exception ex)
{
Utilities.Message(ex);
}
finally
{
trans.Dispose();
}
}//end using database
}
*perry
Message 3 of 3 (141 Views)

Re: blocktablerecord dispose - NOT

08-01-2006 03:26 PM in reply to: *perry
Tony Tanzillo wrote:
>>> BlockTableRecord blkTblRec = new BlockTableRecord();
>
>
> Why are you creating a new instance of a BlockTableRecord,
> if you're not adding a new block definition to the drawing?
>
> That's what's causing the runtime to complain. You're creating
> a new BlockTableRecord, but you don't use it.
>
> Right after that, the variable you assigned that new instance
> to is subsequently reassigned to another instance of that
> same class (returned by GetObject()).
>
> DisposableWrapper sees that your code has problems and so
> it lets you know about that.
>
> If that's exactly what appears in the Autodesk sample code,
> it's quite possible that it predates the AutoCAD 2006 API,
> where there were significant differences in how you handled
> opening/closing of objects.
>
I thought that was the way I was supposed to do it.
But after reading your message, and looking closer at my code I see
that I DONT need to create a "new" record. I made a couple minor changes
to my code (shown below) and the warning went away. Guess I dont need
to call dispose on this object either since I didnt "new" it.
Now I better look though ALL my code for similar problems.
Thanks, Perry
--------------------------------------------------------------------------------
private void checkBlockDef()
{
#if (DEBUG)
Utilities.prompt("\nIn check rev blockdef.");
#endif
int attCount = 0;
using (Database dBase = HostApplicationServices.WorkingDatabase)
{
Transaction trans = dBase.TransactionManager.StartTransaction(); // begin the transaction
try
{
//Now, drill into the database and obtain a reference to the BlockTable
BlockTable blkTbl = (BlockTable)trans.GetObject(dBase.BlockTableId, OpenMode.ForWrite);
//BlockTableRecord blkTblRec = new BlockTableRecord(); //Dont need this!! (first version)
if (blkTbl.Has("TBREVISION"))
{
//check number of attribute definitions
//See notes 1
BlockTableRecord blkTblRec = (BlockTableRecord)trans.GetObject(Utilities.getRevDef(dBase, trans), OpenMode.ForRead, false);
//BlockTableRecord blkTblRec = (BlockTableRecord)trans.GetObject(blkTbl["TBREVISION"], OpenMode.ForRead, false);
if (blkTblRec.HasAttributeDefinitions)
{
foreach (ObjectId objId in blkTblRec)
{
Entity ent = (Entity)trans.GetObject(objId, OpenMode.ForRead);
if (ent is AttributeDefinition)
{
attCount++;
}
ent.Dispose();
}
}
//blkTblRec.Dispose();// dont need this cuz we didnt "new" this object?
}

trans.Commit(); //All done, no errors? Go ahead and commit!
//blkTblRec.Dispose(); //dont need anymore (from first "version")
blkTbl.Dispose();
}
catch (System.Exception ex)
{
Utilities.Message(ex);
}
finally
{
trans.Dispose();
}
}//end using database
}
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.