Message 1 of 7
WblockCloneObjects() causes System.AccessViolationException
Not applicable
09-05-2011
01:17 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi forum,
As mentioned in the subject line, the database-method WblockCloneObjects() keeps causing a System.AccessViolationException with me.
I try to copy the contents (entities) from a xref-database into my current space (which is open in the editor). Therefore I create a new DB and readDwgFile the xref-dwg-file in.
The whole thing is in a foreach loop. Unfortunately it is pretty unpredictory when it occurs. Sometimes it comes sooner, sometimes later. Sometimes the code works without any problems.
At the moment I tried to call WblockCloneObjects() outside of any transaction (therefore the somehow many transactions) but it did not help.
(I am sure the general coding-style could be better too. Please forgive
)
Any ideas? Please help!!! Thx.
try
{
foreach (ObjectId oId in blkDefsXref)
{
// Open xrefDb and copy its modelspace entities for each reference to the current space
//
// Load Xref into sideDb
String xrefPath;
BlockTableRecord btr;
using (Transaction curTr = curDb.TransactionManager.StartTransaction())
{
btr = curTr.GetObject(oId, OpenMode.ForRead) as BlockTableRecord;
xrefPath = btr.PathName;
curTr.Commit();
}
if (xrefPath.Contains(".\\") || !xrefPath.Contains("\\"))
xrefPath = HostApplicationServices.Current.FindFile(xrefPath, curDb, FindFileHint.XRefDrawing);
Database sourceDb = new Database(false, true);
using (sourceDb)
{
sourceDb.ReadDwgFile(xrefPath, System.IO.FileShare.Read, true, "");
ObjectIdCollection idsEntitiesToCopy = new ObjectIdCollection();
using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
{
// Get the entities which are to be cloned:
// Open the source block table record Model space for read
BlockTable sourceBlkTbl = sourceTr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord modelspace_source = sourceTr.GetObject(sourceBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
//
// Make objectIdCollection to be cloned (of entities in source modelspace)
foreach (ObjectId tmpOId in modelspace_source)
{
DBObject tmpO = sourceTr.GetObject(tmpOId, OpenMode.ForRead);
// The next line (if ...) filters the entites (typFilter_EntityClass was defined outside of the try-catch)
if (tmpO.GetType() == typFilter_EntityClass || tmpO.GetType().IsSubclassOf(typFilter_EntityClass))
idsEntitiesToCopy.Add(tmpOId);
}
sourceTr.Commit();
}
// Finally clone the entities for each reference of the current idBlkDef:
ObjectIdCollection oids = getReferencesOfBlockInCurrentSpace(btr);
foreach (ObjectId xrefId in oids)
{
using (Transaction curTr = curDb.TransactionManager.StartTransaction())
{
BlockReference xrefReference = curTr.GetObject(xrefId, OpenMode.ForRead) as BlockReference;
// tranlate the entities to be copied so that they will be optically positioned on the same location in the drawing as the entities in the reference
refOcsOrigin = xrefReference.Position;
refOcsXaxis = xrefReference.GetPlane().GetCoordinateSystem().Xaxis;
refOcsYaxis = xrefReference.GetPlane().GetCoordinateSystem().Yaxis;
refOcsZaxis = xrefReference.Normal;
refRotation = xrefReference.Rotation;
refXscale = xrefReference.ScaleFactors.X;
using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
{
foreach (ObjectId entityOId in idsEntitiesToCopy)
{
Entity ent = sourceTr.GetObject(entityOId, OpenMode.ForWrite) as Entity;
if (refXscale < 0)
ent.TransformBy(Matrix3d.Mirroring(new Plane(sourceDb.Insbase, new Vector3d(0, 1, 0), new Vector3d(0, 0, 1))));
ent.TransformBy(Matrix3d.Rotation(refRotation, new Vector3d(0, 0, 1), sourceDb.Insbase));
ent.TransformBy(Matrix3d.AlignCoordinateSystem(sourceDb.Insbase, new Vector3d(1, 0, 0), new Vector3d(0, 1, 0), new Vector3d(0, 0, 1),
refOcsOrigin, refOcsXaxis, refOcsYaxis, refOcsZaxis));
}
sourceTr.Commit();
}
curTr.Commit();
}
sourceDb.WblockCloneObjects(idsEntitiesToCopy, curDb.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Replace, false);
// undo the translation
using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
{
foreach (ObjectId entityOId in idsEntitiesToCopy)
{
Entity ent = sourceTr.GetObject(entityOId, OpenMode.ForWrite) as Entity;
ent.TransformBy(Matrix3d.AlignCoordinateSystem(refOcsOrigin, refOcsXaxis, refOcsYaxis, refOcsZaxis,
sourceDb.Insbase, new Vector3d(1, 0, 0), new Vector3d(0, 1, 0), new Vector3d(0, 0, 1)));
ent.TransformBy(Matrix3d.Rotation(refRotation * -1, new Vector3d(0, 0, 1), sourceDb.Insbase));
if (refXscale < 0)
ent.TransformBy(Matrix3d.Mirroring(new Plane(sourceDb.Insbase, new Vector3d(0, 1, 0), new Vector3d(0, 0, 1))));
}
sourceTr.Commit();
}
}
}
}
}
catch (System.Exception e)
{
ed.WriteMessage("\nError in else (xref):\n" + e.ToString());
return;
}