.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dictionary.Remove

10 REPLIES 10
Reply
Message 1 of 11
balazsr
2203 Views, 10 Replies

Dictionary.Remove

I am trying to remove same item from a dictionary (I created previously), using the following code:

public virtual bool EraseInsideData(string dictionaryName_in, string[] keys_in) {
bool retVal = true;

using (AcDb.Database db = AcAp.Application.DocumentManager.MdiActiveDocument.Database) {
using (AcDb.Transaction ta = db.TransactionManager.StartTransaction()) {
try {
AcDb.DBDictionary nod = (AcDb.DBDictionary)ta.GetObject(db.NamedObjectsDictionaryId, AcDb.OpenMode.ForRead, false);
AcDb.DBDictionary dictionary = (AcDb.DBDictionary)ta.GetObject(nod.GetAt(dictionaryName_in), AcDb.OpenMode.ForWrite, false);
AcDb.ObjectId id;

foreach (string key in keys_in) {
if (dictionary.Contains(key)) {
id = dictionary.GetAt(key);
dictionary.Remove(id);
}
}

dictionary.Dispose();
nod.Dispose();
ta.Commit();
} catch {
retVal = false;
ta.Abort();
}
}
}
return retVal;
}

I keep getting eWasOpenForWrite exception at Remove().
What I am doing wrong, or generally how I can remove items from a dictionary by key?

Thanks for your support.
10 REPLIES 10
Message 2 of 11
Anonymous
in reply to: balazsr

Are you sure none of the objects in the dictionary
are currently open for write when your code runs?

In order to remove an entry from a dictionary, the
entry must not be open because AutoCAD has to
open it in order to remove the owner dictionary from
the entry's persistent reactors.

You should also open the removed objects and
call erase() on each, after removing them.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5798486@discussion.autodesk.com...
I am trying to remove same item from a dictionary (I created previously), using the following code:

public virtual bool EraseInsideData(string dictionaryName_in, string[] keys_in) {
bool retVal = true;

using (AcDb.Database db = AcAp.Application.DocumentManager.MdiActiveDocument.Database) {
using (AcDb.Transaction ta = db.TransactionManager.StartTransaction()) {
try {
AcDb.DBDictionary nod = (AcDb.DBDictionary)ta.GetObject(db.NamedObjectsDictionaryId, AcDb.OpenMode.ForRead, false);
AcDb.DBDictionary dictionary = (AcDb.DBDictionary)ta.GetObject(nod.GetAt(dictionaryName_in), AcDb.OpenMode.ForWrite, false);
AcDb.ObjectId id;

foreach (string key in keys_in) {
if (dictionary.Contains(key)) {
id = dictionary.GetAt(key);
dictionary.Remove(id);
}
}

dictionary.Dispose();
nod.Dispose();
ta.Commit();
} catch {
retVal = false;
ta.Abort();
}
}
}
return retVal;
}

I keep getting eWasOpenForWrite exception at Remove().
What I am doing wrong, or generally how I can remove items from a dictionary by key?

Thanks for your support.
Message 3 of 11
balazsr
in reply to: balazsr

I am not sure I clearly understand your solution.
I store a string-string (key-value) pair at the dictionary.

So, I just like to remove the key-value (TypedValue) string pairs from the dictionary.
What Erase() should I call? It is clear I can delete Entity by calling entity.Erase(), but it is a simple string pair, so what shell I do?

I am under 2006 anyway.
Message 4 of 11
Anonymous
in reply to: balazsr

A DBDictionary doesn't store strings as values.

It stores strings as keys and ObjectIds as values,
and nothing else.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5798626@discussion.autodesk.com...
I am not sure I clearly understand your solution.
I store a string-string (key-value) pair at the dictionary.

So, I just like to remove the key-value (TypedValue) string pairs from the dictionary.
What Erase() should I call? It is clear I can delete Entity by calling entity.Erase(), but it is a simple string pair, so what shell I do?

I am under 2006 anyway.
Message 5 of 11
balazsr
in reply to: balazsr

Oh, I see. But, If I like to erase a key with it's value as well, what should I do, because as I mentioned the dictionary.Remove() not works with key or ObjectId as well (the eWasOpenForWrite exception).

Do you have a working solution for this?

Or I should remove items from the dictionary the following way?:
- Get the Xrecord of the key,
- Erase that,
- than erase the key?

if (dictionary.Contains(key)) {
id = dictionary.GetAt(key);
record = (AcDb.Xrecord)ta.GetObject(id, AcDb.OpenMode.ForWrite, false);
record.Erase();
dictionary.Remove(id);
}

Kind Regards.
Message 6 of 11
balazsr
in reply to: balazsr

The problem was when creating the dictionary item, I did not Dispose() the Xrecords contiaining the values:

AcDb.Xrecord record;
for (int i = 0; i < keys_in.Length; i++) {
record = new AcDb.Xrecord();
record.Data = new AcDb.ResultBuffer(new AcDb.TypedValue((int)AcDb.DxfCode.Text, values_in));
dictionary.SetAt(keys_in, record);
record.Dispose(); // This was missing!
}

Regards.
Message 7 of 11
SRSDS
in reply to: balazsr

Can someone shed some light on Tony's comment on removing a dictionary entry?

"You should also open the removed objects and call erase() on each, after removing them."

balazsr asked what he meant but there was no reply.

Does simply removing the dictionary entry still leave something residual in the memory?

Message 8 of 11
artc2
in reply to: SRSDS

The remove method on a dictionary simply removes that key/objectId pair from the dictionary and also removes the dictionary as a persistent reactor on the object identified by the objectId. But, that object is still in the Database - it just no longer has an owner. Calling erase on that object marks it as erased so that it won't be saved and so that anything that tries to open it it will get an error about it being erased (unless the open specifically says to open erased objects). Erasing it to prevent saving it is redundant since objects without owners are not saved anyway.
Message 9 of 11
SRSDS
in reply to: artc2

Just to be clear.

Contrary to what Tony was saying, erasing is unnecessary.

Tony's word was gospel a while back. This would have been a nice argument. 🙂

Message 10 of 11
ActivistInvestor
in reply to: SRSDS

The purpose of erasing an object that has been removed from a dictionary is to ensure that a subsequent attempt to open it will fail because the object is effectively erased.

 

 


@SRSDS wrote:

Just to be clear.

Contrary to what Tony was saying, erasing is unnecessary.

Tony's word was gospel a while back. This would have been a nice argument. 🙂


 

Message 11 of 11
SRSDS
in reply to: ActivistInvestor

That makes sense. Thank you.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost