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

Open objects multiply times, within transactions

6 REPLIES 6
Reply
Message 1 of 7
t.willey
383 Views, 6 Replies

Open objects multiply times, within transactions

I am writting some code that needs to compare text objects that are stacked
on top of each other, this I have been able to do. I then need to compare
them to see if they have english words within the text string, this I have
done. Now I'm trying to make the routine better, as first I would have one
select the objects, but now I want to have the program search all of model
space for the text objects. It will open them, and find all the others that
are on top of them (in the same place in essence), but I have to open them a
second time to make the changes, and I get the error
"System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. ---> System.InvalidOperationException:
Operation is not valid due to the current state of the object."
So I'm assuming it is because the object is already open.

So the question is how do I change an entity that I have open once for read,
then need to upgrade it's open status, but I don't hold onto the entity's
object? I was hoping I could explain this in a manner that I wouldn't have
to post my code, but I dont' think I can. Here is the part I'm talking
about. Doesn't look like it will post to well, so I'm attaching a text file
that has same code. Thanks in advance.

public void FindAssociatedText() {
MyDia = new ForTesting_Form();
Document Doc = acadApp.DocumentManager.MdiActiveDocument;
Database Db = Doc.Database;
using (Transaction Trans =
Db.TransactionManager.StartTransaction()) {
LayerTable LayTbl = (LayerTable)Trans.GetObject(Db.LayerTableId,
OpenMode.ForRead);
if (!LayTbl.Has("NotEnglish")) {
LayTbl.UpgradeOpen();
LayerTableRecord ltr = new LayerTableRecord();
ltr.Name = "NotEnglish";
ltr.IsFrozen = true;
LayTbl.Add(ltr);
Trans.AddNewlyCreatedDBObject(ltr, true);
}
BlockTable bt = (BlockTable)Trans.GetObject(Db.BlockTableId,
OpenMode.ForRead);
BlockTableRecord btr =
(BlockTableRecord)Trans.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead);
ArrayList ObjIdArList = new ArrayList();
foreach (ObjectId tempObjId in btr) {
DBText tempText = Trans.GetObject(tempObjId, OpenMode.ForRead) as
DBText;
if (tempText != null)
ObjIdArList.Add(tempObjId);
}
for (int i = 0; i < ObjIdArList.Count; ++i) {
ArrayList tempObjIdArList = new ArrayList();
Entity tempEnt =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
for (int j = i + 1; j < ObjIdArList.Count; ++j) {
Point3dCollection PtCol = new Point3dCollection();
Entity tempEnt2 =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
tempEnt.BoundingBoxIntersectWith(tempEnt2,
Intersect.OnBothOperands, PtCol, 0, 0);
if (!PtCol.Count.Equals(0)) {
if (tempObjIdArList.Count.Equals(0)) {
tempObjIdArList.Add(tempEnt.ObjectId);
tempObjIdArList.Add(tempEnt2.ObjectId);
}
else
tempObjIdArList.Add(tempEnt2.ObjectId);
}
}
int cnt = 0;
foreach (ObjectId tempObjId in tempObjIdArList) {
bool IsEnglish = false;
DBText tempText = (DBText)Trans.GetObject(tempObjId,
OpenMode.ForRead);
tempText.UpgradeOpen();
string Str = tempText.TextString;
string[] StrArr = Str.Split(' ');
ListViewItem lvi = new ListViewItem(Str);
lvi.Tag = tempObjId;
lvi.SubItems.Add(tempText.Layer);
MyDia.AllStringsView.Items.Add(lvi);
foreach (string tempStr in StrArr) {
using (StreamReader sr = new
StreamReader("C:\\MyCustom\\Programs\\ALLUP&R.DIC")) {
while (!IsEnglish && sr.Peek() != -1) {
string DictStr = sr.ReadLine();
if (string.Compare(DictStr, tempStr, true).Equals(0)) {
IsEnglish = true;
++cnt;
}
}
}
}
if (!IsEnglish) tempText.Layer = "NotEnglish";
else {
ListViewItem lviClone = (ListViewItem)lvi.Clone();
MyDia.EngStringsView.Items.Add(lviClone);
}
ObjIdArList.Remove(tempObjId);
}
if (!tempObjIdArList.Count.Equals(0)) {
if (cnt.Equals(0)) {
MyDia.AllStringsView.Visible = true;
MyDia.EngStringsView.Visible = false;
MyDia.TogBtn.Text = "Show English";
}
if (!cnt.Equals(1))
ShowMyDialog(Doc, Trans);
Trans.Commit();
}
}
}

}

--

Tim
"A blind man lets nothing block his vision."
6 REPLIES 6
Message 2 of 7
pavlos.katsonis
in reply to: t.willey

Why don't you store the objects themselves instead of their IDs? This way you won't have to reopen them.
Message 3 of 7
t.willey
in reply to: t.willey

I thought I heard that it is better to store the ID, that is why I did it
that way. Do you believe this not to be true?

--

Tim
"A blind man lets nothing block his vision."


wrote in message news:5758718@discussion.autodesk.com...
Why don't you store the objects themselves instead of their IDs? This way
you won't have to reopen them.
Message 4 of 7
Anonymous
in reply to: t.willey

Tim - If everthing you're doing is taking place within the
boundary of a transaction, you can keep the DBObjects
open.

The rule about using DBObjects is that you shouldn't use
them after the transaction you got them from, has ended
(comitted or aborted).

Also, if you're using .NET 2.0, then you can avoid some
typecasting overhead by not using ArrayList for storing
lists of objects of a known type.

For example, if your ArrayList contains only DBText objects,
you can avoid the casting overhead, by using List,
or List instead (the latter if everything in the list is
an Entity, or any type derived from it).

To make things simple when I need to do that kind of thing,
I use a custom class that functionally acts as both a List<>
and a transaction (see attached).

--
http://www.caddzone.com

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

wrote in message news:5758696@discussion.autodesk.com...
I am writting some code that needs to compare text objects that are stacked
on top of each other, this I have been able to do. I then need to compare
them to see if they have english words within the text string, this I have
done. Now I'm trying to make the routine better, as first I would have one
select the objects, but now I want to have the program search all of model
space for the text objects. It will open them, and find all the others that
are on top of
them (in the same place in essence), but I have to open them a
second time to make the changes, and I get the error
"System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. ---> System.InvalidOperationException:
Operation is not valid due to the current state of the object."
So I'm assuming it is because the object is already open.

So the question is how do I change an entity that I have open once for read,
then need to upgrade i
t's open status, but I don't hold onto the entity's
object? I was hoping I could explain this in a manner that I wouldn't have
to post my code, but I dont' think I can. Here is the part I'm talking
about. Doesn't look like it will post to well, so I'm attaching a text file
that has same code. Thanks in advance.

public void FindAssociatedText() {
MyDia = new ForTesting_Form();
Document Doc = acadApp.DocumentManager.MdiActiveDocument;
Datab
ase Db = Doc.Database;
using (Transaction Trans =
Db.TransactionManager.StartTransaction()) {
LayerTable LayTbl = (LayerTable)Trans.GetObject(Db.LayerTableId,
OpenMode.ForRead);
if (!LayTbl.Has("NotEnglish")) {
LayTbl.UpgradeOpen();
LayerTableRecord ltr = new LayerTableRecord();
ltr.Name = "NotEnglish";
ltr.IsFrozen = true;
LayTbl.Add(ltr);
Trans.AddNewlyCreatedDBObject(ltr, true)
;
}
BlockTable bt = (BlockTable)Trans.GetObject(Db.BlockTableId,
OpenMode.ForRead);
BlockTableRecord btr =
(BlockTableRecord)Trans.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead);
ArrayList ObjIdArList = new ArrayList();
foreach (ObjectId tempObjId in btr) {
DBText tempText = Trans.GetObject(tempObjId, OpenMode.ForRead) as
DBText;
if (tempText != null)
ObjIdArList.Add(tempO
bjId);
}
for (int i = 0; i < ObjIdArList.Count; ++i) {
ArrayList tempObjIdArList = new ArrayList();
Entity tempEnt =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
for (int j = i + 1; j < ObjIdArList.Count; ++j) {
Point3dCollection PtCol = new Point3dCollection();
Entity tempEnt2 =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
tempEnt.BoundingBox
IntersectWith(tempEnt2,
Intersect.OnBothOperands, PtCol, 0, 0);
if (!PtCol.Count.Equals(0)) {
if (tempObjIdArList.Count.Equals(0)) {
tempObjIdArList.Add(tempEnt.ObjectId);
tempObjIdArList.Add(tempEnt2.ObjectId);
}
else
tempObjIdArList.Add(tempEnt2.ObjectId);
}
}
int cnt = 0;
foreach (ObjectId tempObjId in tempObjIdArList) {
bool IsEnglish 3D false;
DBText tempText = (DBText)Trans.GetObject(tempObjId,
OpenMode.ForRead);
tempText.UpgradeOpen();
string Str = tempText.TextString;
string[] StrArr = Str.Split(' ');
ListViewItem lvi = new ListViewItem(Str);
lvi.Tag = tempObjId;
lvi.SubItems.Add(tempText.Layer);
MyDia.AllStringsView.Items.Add(lvi);
foreach (string tempStr in StrArr) {
using (StreamReader
sr = new
StreamReader("C:\\MyCustom\\Programs\\ALLUP&R.DIC")) {
while (!IsEnglish && sr.Peek() != -1) {
string DictStr = sr.ReadLine();
if (string.Compare(DictStr, tempStr, true).Equals(0)) {
IsEnglish = true;
++cnt;
}
}
}
}
if (!IsEnglish) tempText.Layer = "NotEnglish";
else {
ListViewItem lviClone = (ListViewIte
m)lvi.Clone();
MyDia.EngStringsView.Items.Add(lviClone);
}
ObjIdArList.Remove(tempObjId);
}
if (!tempObjIdArList.Count.Equals(0)) {
if (cnt.Equals(0)) {
MyDia.AllStringsView.Visible = true;
MyDia.EngStringsView.Visible = false;
MyDia.TogBtn.Text = "Show English";
}
if (!cnt.Equals(1))
ShowMyDialog(Doc, Trans);
Trans.Commit();

}
}
}

}

--

Tim
"A blind man lets nothing block his vision."
Message 5 of 7
Anonymous
in reply to: t.willey

Sorry, looks like Autodesks news server mangled
my .txt file (unbelievable). Since I can't post a
zip file here either, you can just get it here:

http://www.caddzone.com/DBObjectSet.cs

--
http://www.caddzone.com

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

"Tony Tanzillo" wrote in message news:5758799@discussion.autodesk.com...
Tim - If everthing you're doing is taking place within the
boundary of a transaction, you can keep the DBObjects
open.

The rule about using DBObjects is that you shouldn't use
them after the transaction you got them from, has ended
(comitted or aborted).

Also, if you're using .NET 2.0, then you can avoid some
typecasting overhead by not using ArrayList for storing
lists of objects of a known type.

For example, if your ArrayList contains only DBText objects,
you can avoid the ca
sting overhead, by using List,
or List instead (the latter if everything in the list is
an Entity, or any type derived from it).

To make things simple when I need to do that kind of thing,
I use a custom class that functionally acts as both a List<>
and a transaction (see attached).

--
http://www.caddzone.com

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

wrote in message news:5758696@dis
cussion.autodesk.com...
I am writting some code that needs to compare text objects that are stacked
on top of each other, this I have been able to do. I then need to compare
them to see if they have english words within the text string, this I have
done. Now I'm trying to make the routine better, as first I would have one
select the objects, but now I want to have the program search all of model
space for the text objects. It will open them, and find all the others t
hat
are on top of
them (in the same place in essence), but I have to open them a
second time to make the changes, and I get the error
"System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. ---> System.InvalidOperationException:
Operation is not valid due to the current state of the object."
So I'm assuming it is because the object is already open.

So the question is how do I change an entity that I have open once for read,20
then need to upgrade i
t's open status, but I don't hold onto the entity's
object? I was hoping I could explain this in a manner that I wouldn't have
to post my code, but I dont' think I can. Here is the part I'm talking
about. Doesn't look like it will post to well, so I'm attaching a text file
that has same code. Thanks in advance.

public void FindAssociatedText() {
MyDia = new ForTesting_Form();
Document Doc = acadApp.DocumentManager.MdiActive
Document;
Datab
ase Db = Doc.Database;
using (Transaction Trans =
Db.TransactionManager.StartTransaction()) {
LayerTable LayTbl = (LayerTable)Trans.GetObject(Db.LayerTableId,
OpenMode.ForRead);
if (!LayTbl.Has("NotEnglish")) {
LayTbl.UpgradeOpen();
LayerTableRecord ltr = new LayerTableRecord();
ltr.Name = "NotEnglish";
ltr.IsFrozen = true;
LayTbl.Add(ltr);
Trans.AddNewl
yCreatedDBObject(ltr, true)
;
}
BlockTable bt = (BlockTable)Trans.GetObject(Db.BlockTableId,
OpenMode.ForRead);
BlockTableRecord btr =
(BlockTableRecord)Trans.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead);
ArrayList ObjIdArList = new ArrayList();
foreach (ObjectId tempObjId in btr) {
DBText tempText = Trans.GetObject(tempObjId, OpenMode.ForRead) as
DBText;
if (tempText != null)

ObjIdArList.Add(tempO
bjId);
}
for (int i = 0; i < ObjIdArList.Count; ++i) {
ArrayList tempObjIdArList = new ArrayList();
Entity tempEnt =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
for (int j = i + 1; j < ObjIdArList.Count; ++j) {
Point3dCollection PtCol = new Point3dCollection();
Entity tempEnt2 =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);

tempEnt.BoundingBox
IntersectWith(tempEnt2,
Intersect.OnBothOperands, PtCol, 0, 0);
if (!PtCol.Count.Equals(0)) {
if (tempObjIdArList.Count.Equals(0)) {
tempObjIdArList.Add(tempEnt.ObjectId);
tempObjIdArList.Add(tempEnt2.ObjectId);
}
else
tempObjIdArList.Add(tempEnt2.ObjectId);
}
}
int cnt = 0;
foreach (ObjectId tempObjId in tempObjIdArList
) {
bool IsEnglish 3D false;
DBText tempText = (DBText)Trans.GetObject(tempObjId,
OpenMode.ForRead);
tempText.UpgradeOpen();
string Str = tempText.TextString;
string[] StrArr = Str.Split(' ');
ListViewItem lvi = new ListViewItem(Str);
lvi.Tag = tempObjId;
lvi.SubItems.Add(tempText.Layer);
MyDia.AllStringsView.Items.Add(lvi);
foreach (string tempStr in StrArr) {

using (StreamReader
sr = new
StreamReader("C:\\MyCustom\\Programs\\ALLUP&R.DIC")) {
while (!IsEnglish && sr.Peek() != -1) {
string DictStr = sr.ReadLine();
if (string.Compare(DictStr, tempStr, true).Equals(0)) {
IsEnglish = true;
++cnt;
}
}
}
}
if (!IsEnglish) tempText.Layer = "NotEnglish";
else {
Li
stViewItem lviClone = (ListViewIte
m)lvi.Clone();
MyDia.EngStringsView.Items.Add(lviClone);
}
ObjIdArList.Remove(tempObjId);
}
if (!tempObjIdArList.Count.Equals(0)) {
if (cnt.Equals(0)) {
MyDia.AllStringsView.Visible = true;
MyDia.EngStringsView.Visible = false;
MyDia.TogBtn.Text = "Show English";
}
if (!cnt.Equals(1))
ShowMyDialog(Doc, Tra
ns);
Trans.Commit();

}
}
}

}

--

Tim
"A blind man lets nothing block his vision."
Message 6 of 7
pavlos.katsonis
in reply to: t.willey

Tonny answered for me 🙂
Message 7 of 7
t.willey
in reply to: t.willey

Thanks Tony and Pavlos. I have learned something new. Tony I'm still using
.Net 1.1, but I will keep the idea (and sample) in mind when I move to the
newer .Net framworks.

--

Tim
"A blind man lets nothing block his vision."


wrote in message news:5758696@discussion.autodesk.com...
I am writting some code that needs to compare text objects that are stacked
on top of each other, this I have been able to do. I then need to compare
them to see if they have english words within the text string, this I have
done. Now I'm trying to make the routine better, as first I would have one
select the objects, but now I want to have the program search all of model
space for the text objects. It will open them, and find all the others that
are on top of
them (in the same place in essence), but I have to open them a
second time to make the changes, and I get the error
"System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. ---> System.InvalidOperationException:
Operation is not valid due to the current state of the object."
So I'm assuming it is because the object is already open.

So the question is how do I change an entity that I have open once for read,
then need to upgrade i
t's open status, but I don't hold onto the entity's
object? I was hoping I could explain this in a manner that I wouldn't have
to post my code, but I dont' think I can. Here is the part I'm talking
about. Doesn't look like it will post to well, so I'm attaching a text file
that has same code. Thanks in advance.

public void FindAssociatedText() {
MyDia = new ForTesting_Form();
Document Doc = acadApp.DocumentManager.MdiActiveDocument;
Datab
ase Db = Doc.Database;
using (Transaction Trans =
Db.TransactionManager.StartTransaction()) {
LayerTable LayTbl = (LayerTable)Trans.GetObject(Db.LayerTableId,
OpenMode.ForRead);
if (!LayTbl.Has("NotEnglish")) {
LayTbl.UpgradeOpen();
LayerTableRecord ltr = new LayerTableRecord();
ltr.Name = "NotEnglish";
ltr.IsFrozen = true;
LayTbl.Add(ltr);
Trans.AddNewlyCreatedDBObject(ltr, true)
;
}
BlockTable bt = (BlockTable)Trans.GetObject(Db.BlockTableId,
OpenMode.ForRead);
BlockTableRecord btr =
(BlockTableRecord)Trans.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead);
ArrayList ObjIdArList = new ArrayList();
foreach (ObjectId tempObjId in btr) {
DBText tempText = Trans.GetObject(tempObjId, OpenMode.ForRead) as
DBText;
if (tempText != null)
ObjIdArList.Add(tempO
bjId);
}
for (int i = 0; i < ObjIdArList.Count; ++i) {
ArrayList tempObjIdArList = new ArrayList();
Entity tempEnt =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
for (int j = i + 1; j < ObjIdArList.Count; ++j) {
Point3dCollection PtCol = new Point3dCollection();
Entity tempEnt2 =
(Entity)Trans.GetObject((ObjectId)ObjIdArList, OpenMode.ForRead);
tempEnt.BoundingBox
IntersectWith(tempEnt2,
Intersect.OnBothOperands, PtCol, 0, 0);
if (!PtCol.Count.Equals(0)) {
if (tempObjIdArList.Count.Equals(0)) {
tempObjIdArList.Add(tempEnt.ObjectId);
tempObjIdArList.Add(tempEnt2.ObjectId);
}
else
tempObjIdArList.Add(tempEnt2.ObjectId);
}
}
int cnt = 0;
foreach (ObjectId tempObjId in tempObjIdArList) {
bool IsEnglish 3D false;
DBText tempText = (DBText)Trans.GetObject(tempObjId,
OpenMode.ForRead);
tempText.UpgradeOpen();
string Str = tempText.TextString;
string[] StrArr = Str.Split(' ');
ListViewItem lvi = new ListViewItem(Str);
lvi.Tag = tempObjId;
lvi.SubItems.Add(tempText.Layer);
MyDia.AllStringsView.Items.Add(lvi);
foreach (string tempStr in StrArr) {
using (StreamReader
sr = new
StreamReader("C:\\MyCustom\\Programs\\ALLUP&R.DIC")) {
while (!IsEnglish && sr.Peek() != -1) {
string DictStr = sr.ReadLine();
if (string.Compare(DictStr, tempStr, true).Equals(0)) {
IsEnglish = true;
++cnt;
}
}
}
}
if (!IsEnglish) tempText.Layer = "NotEnglish";
else {
ListViewItem lviClone = (ListViewIte
m)lvi.Clone();
MyDia.EngStringsView.Items.Add(lviClone);
}
ObjIdArList.Remove(tempObjId);
}
if (!tempObjIdArList.Count.Equals(0)) {
if (cnt.Equals(0)) {
MyDia.AllStringsView.Visible = true;
MyDia.EngStringsView.Visible = false;
MyDia.TogBtn.Text = "Show English";
}
if (!cnt.Equals(1))
ShowMyDialog(Doc, Trans);
Trans.Commit();

}
}
}

}

--

Tim
"A blind man lets nothing block his vision."

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