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

Corrupt Memory Error

12 REPLIES 12
Reply
Message 1 of 13
Anonymous
1328 Views, 12 Replies

Corrupt Memory Error

I need help in trying to track down an elusive bug. I’ve written a fairly sophisticated c# routine that creates blocks based on data stored in a database. My users have discovered that they can run the routine once to successfully create the blocks in their drawings. But if they try to run the routine a second time on the same drawing before closing this drawing, an error appears when the routine is trying to commit the transaction. The error that comes up is “Attempted to read or write protected memory” and then AutoCAD will crash. If the user saves and closes the drawing before running the routine a second time, the error does not appear.

I’ve done some searching on this forum and the internet for the answer and have implemented some changes to my application to try to solve this issue. One of the first measures I did was to make sure that I’ve disposed all objects that I’ve accessed through the GetObject(OpenMode) method and not dispose any object opened by a transaction. Then I made sure that my code was not accessing the block table or the modelspace record more than once at the same time in my routine. The error still occurs as before.

I use selection sets occasionally in my application to retrieve existing blocks. Should I be disposing of any of the objects associated with the selection sets?

What other measures can I take to try to solve this issue?

Any help would be greatly appreciated.

Stephen
12 REPLIES 12
Message 2 of 13
Anonymous
in reply to: Anonymous

This isn't a TV game show.

Without seeing your code or little or nothing about it,
there's nothing anyone here can tell you.

--
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


wrote in message news:6136619@discussion.autodesk.com...
I need help in trying to track down an elusive bug. I've written a fairly
sophisticated c# routine that creates blocks based on data stored in a
database. My users have discovered that they can run the routine once to
successfully create the blocks in their drawings. But if they try to run the
routine a second time on the same drawing before closing this drawing, an
error appears when the routine is trying to commit the transaction. The
error that comes up is "Attempted to read or write protected memory" and
then AutoCAD will crash. If the user saves and closes the drawing before
running the routine a second time, the error does not appear. I've done some
searching on this forum and the internet for the answer and have implemented
some changes to my application to try to solve this issue. One of the first
measures I did was to make sure that I've disposed all objects that I've
accessed through the GetObject(OpenMode) method and not dispose any object
opened by a transaction. Then I made sure that my code was not accessing the
block table or the modelspace record more than once at the same time in my
routine. The error still occurs as before. I use selection sets occasionally
in my application to retrieve existing blocks. Should I be disposing of any
of the objects associated with the selection sets? What other measures can I
take to try to solve this issue? Any help would be greatly appreciated.
Stephen
Message 3 of 13
Anonymous
in reply to: Anonymous

I didn't post my code for this application because it is close to 3,000 lines long.

I wasn't asking anyone to analyse my code for me, figuring that it would be too much to ask someone to look through that much code to see if they could find something wrong.

I was hoping that someone else had a similar problem and could tell me how they solved it. If not, I was hoping someone had some tips that would point me in the right direction for tracking down the issue.
Message 4 of 13
Anonymous
in reply to: Anonymous

Sorry, I should have said "relevant parts" of your code.

IOW, your entire project isn't necessary, just the code
that opens and access the database, which runs just
before the failure.

Unfortunately, an error when the drawing is saved can
have many causes, so even if someone else may have
come across it, it could be a completely different cause.

--
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


wrote in message news:6137083@discussion.autodesk.com...
I didn't post my code for this application because it is close to 3,000
lines long. I wasn't asking anyone to analyse my code for me, figuring that
it would be too much to ask someone to look through that much code to see if
they could find something wrong. I was hoping that someone else had a
similar problem and could tell me how they solved it. If not, I was hoping
someone had some tips that would point me in the right direction for
tracking down the issue.
Message 5 of 13
Anonymous
in reply to: Anonymous

I've included the starting routine in this post. It won't give a lot of details about what the routine is doing but illustrates how the transactions and blocktable are being handled.

Thanks for all your help, Tony.

{code}
public void Create()
{
this.DeleteLog();

if (this.CopyMDBFile())
{
this.AddRegAppTableRecord();

this.trans = this.dwgDB.TransactionManager.StartTransaction();

// Open the block table.

BlockTable bt = null;

try
{
// Make sure a bold text style has been created when needed.

if (AppPrefs.HasBoldText && !this.DwgHasTextStyle(Constants.DataBox.BoldStyleName))
{
this.ed.WriteMessage("A bold textstyle must be defined.");
this.trans.Abort();
}
else
{
this.AddDataboxLayers();
this.InsertPointBlock();
this.FindCurrentPointBlocks();

// Get the list of well IDs.

List wellIDs = DataManager.GetUniqueValues(AppPrefs.DataSourceName, AppPrefs.TableName, AppPrefs.TitleField);

if (wellIDs.Count > 0)
{
this.insertedBlocks = new List(wellIDs.Count);

bt = (BlockTable)this.trans.GetObject(this.dwgDB.BlockTableId, OpenMode.ForWrite);
DataBox currDataBox = new DataBox(this.dbLayers, this.trans, bt);

// Initialize and display the status form.

StatusForm statusForm = new StatusForm();
statusForm.TotalDataboxes = wellIDs.Count;
Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(statusForm);

// Create a databox for each well ID.

foreach (string wellID in wellIDs)
{
System.Windows.Forms.Application.DoEvents();

if (!statusForm.StopRequested)
{
// Update the status form.

statusForm.CurrDataboxID = wellID;

// Initialize the DataBox class.

currDataBox.WellID = wellID;

// Track the blocks that have been inserted.

this.insertedBlocks.Add(currDataBox.BlockName);

// Create the databox in AutoCAD.

currDataBox.Draw();

this.InsertDataBoxPointBlock(currDataBox, bt);
}
else
{
break;
}
}

if (!statusForm.StopRequested)
{
// After all of the databoxes have been created, check to see if
// there are any leftover databoxes from a previous running of
// this routine and remove them.

this.DeleteOrphans(bt);

// Successful run of databox creation, commit the transactions.

this.trans.Commit();

// Zoom the current view to the extents of the drawing.

Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute("zoom e\n", true, false, false);
}
else
{
this.trans.Abort();
}

// Close the status form.

statusForm.Close();
}
else
{
this.ed.WriteMessage("No IDs found for specified title field.");
this.trans.Abort();
}
}
}
catch (Autodesk.AutoCAD.Runtime.Exception aex)
{
this.ed.WriteMessage("AutoCAD error: " + aex.Message);
this.trans.Abort();
}
catch (System.Exception ex)
{
this.ed.WriteMessage("Error: " + ex.Message);
this.trans.Abort();
}
finally
{
if (bt != null)
{
bt.Dispose();
}
this.trans.Dispose();
}

// Delete the copied .mdb file.

this.DeleteMDBFile();
}
}

{code}
Message 6 of 13
Anonymous
in reply to: Anonymous

You'll need to attach it, since I can't read it in
a newsreader.

--
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


wrote in message news:6137198@discussion.autodesk.com...
I've included the starting routine in this post. It won't give a lot of
details about what the routine is doing but illustrates how the transactions
and blocktable are being handled. Thanks for all your help, Tony. {code}
public void Create() { this.DeleteLog(); if (this.CopyMDBFile()) {
this.AddRegAppTableRecord(); this.trans =
this.dwgDB.TransactionManager.StartTransaction(); // Open the block table.
BlockTable bt = null; try { // Make sure a bold text style has been created
when needed. if (AppPrefs.HasBoldText &&
!this.DwgHasTextStyle(Constants.DataBox.BoldStyleName)) {
this.ed.WriteMessage("A bold textstyle must be defined.");
this.trans.Abort(); } else { this.AddDataboxLayers();
this.InsertPointBlock(); this.FindCurrentPointBlocks(); // Get the list of
well IDs. List wellIDs =
DataManager.GetUniqueValues(AppPrefs.DataSourceName, AppPrefs.TableName,
AppPrefs.TitleField); if (wellIDs.Count > 0) { this.insertedBlocks = new
List(wellIDs.Count); bt =
(BlockTable)this.trans.GetObject(this.dwgDB.BlockTableId,
OpenMode.ForWrite); DataBox currDataBox = new DataBox(this.dbLayers,
this.trans, bt); // Initialize and display the status form. StatusForm
statusForm = new StatusForm(); statusForm.TotalDataboxes = wellIDs.Count;
Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(statusForm);
// Create a databox for each well ID. foreach (string wellID in wellIDs) {
System.Windows.Forms.Application.DoEvents(); if (!statusForm.StopRequested)
{ // Update the status form. statusForm.CurrDataboxID = wellID; //
Initialize the DataBox class. currDataBox.WellID = wellID; // Track the
blocks that have been inserted.
this.insertedBlocks.Add(currDataBox.BlockName); // Create the databox in
AutoCAD. currDataBox.Draw(); this.InsertDataBoxPointBlock(currDataBox,
bt); } else { break; } } if (!statusForm.StopRequested) { // After all of
the databoxes have been created, check to see if // there are any leftover
databoxes from a previous running of // this routine and remove them.
this.DeleteOrphans(bt); // Successful run of databox creation, commit the
transactions. this.trans.Commit(); // Zoom the current view to the extents
of the drawing.
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute("zoom
e\n", true, false, false); } else { this.trans.Abort(); } // Close the
status form. statusForm.Close(); } else { this.ed.WriteMessage("No IDs found
for specified title field."); this.trans.Abort(); } } } catch
(Autodesk.AutoCAD.Runtime.Exception aex) { this.ed.WriteMessage("AutoCAD
error: " + aex.Message); this.trans.Abort(); } catch (System.Exception ex)
{ this.ed.WriteMessage("Error: " + ex.Message); this.trans.Abort(); }
finally { if (bt != null) { bt.Dispose(); } this.trans.Dispose(); } //
Delete the copied .mdb file. this.DeleteMDBFile(); } } {code}
Message 7 of 13
Anonymous
in reply to: Anonymous


Try posting it in Rich Text.

 

Joe ...


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
I've
included the starting routine in this post. It won't give a lot of details
about what the routine is doing but illustrates how the transactions and
blocktable are being handled. Thanks for all your help, Tony. {code} public
void Create() { this.DeleteLog(); if (this.CopyMDBFile()) {
this.AddRegAppTableRecord(); this.trans =
this.dwgDB.TransactionManager.StartTransaction(); // Open the block table.
BlockTable bt = null; try { // Make sure a bold text style has been created
when needed. if (AppPrefs.HasBoldText &&
!this.DwgHasTextStyle(Constants.DataBox.BoldStyleName)) {
this.ed.WriteMessage("A bold textstyle must be defined."); this.trans.Abort();
} else { this.AddDataboxLayers(); this.InsertPointBlock();
this.FindCurrentPointBlocks(); // Get the list of well IDs. List
wellIDs = DataManager.GetUniqueValues(AppPrefs.DataSourceName,
AppPrefs.TableName, AppPrefs.TitleField); if (wellIDs.Count > 0) {
this.insertedBlocks = new List(wellIDs.Count); bt =
(BlockTable)this.trans.GetObject(this.dwgDB.BlockTableId, OpenMode.ForWrite);
DataBox currDataBox = new DataBox(this.dbLayers, this.trans, bt); //
Initialize and display the status form. StatusForm statusForm = new
StatusForm(); statusForm.TotalDataboxes = wellIDs.Count;
Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(statusForm);
// Create a databox for each well ID. foreach (string wellID in wellIDs) {
System.Windows.Forms.Application.DoEvents(); if (!statusForm.StopRequested) {
// Update the status form. statusForm.CurrDataboxID = wellID; // Initialize
the DataBox class. currDataBox.WellID = wellID; // Track the blocks that have
been inserted. this.insertedBlocks.Add(currDataBox.BlockName); // Create the
databox in AutoCAD. currDataBox.Draw();
this.InsertDataBoxPointBlock(currDataBox, bt); } else { break; } } if
(!statusForm.StopRequested) { // After all of the databoxes have been created,
check to see if // there are any leftover databoxes from a previous running of
// this routine and remove them. this.DeleteOrphans(bt); // Successful run of
databox creation, commit the transactions. this.trans.Commit(); // Zoom the
current view to the extents of the drawing.
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute("zoom
e\n", true, false, false); } else { this.trans.Abort(); } // Close the status
form. statusForm.Close(); } else { this.ed.WriteMessage("No IDs found for
specified title field."); this.trans.Abort(); } } } catch
(Autodesk.AutoCAD.Runtime.Exception aex) { this.ed.WriteMessage("AutoCAD
error: " + aex.Message); this.trans.Abort(); } catch (System.Exception ex) {
this.ed.WriteMessage("Error: " + ex.Message); this.trans.Abort(); } finally {
if (bt != null) { bt.Dispose(); } this.trans.Dispose(); } // Delete the copied
.mdb file. this.DeleteMDBFile(); } } {code}
Message 8 of 13
Anonymous
in reply to: Anonymous

Sorry about that. I've attached the code to this reply.

Let me know if you want more examples and what I should be including.

Thanks,
Stephen
Message 9 of 13
Anonymous
in reply to: Anonymous

I'm afraid your code looks OK.



I think you should post a bit more, the things we can see in this code are ok.



However, we don't know what is happening in



DataBox.Draw()



InsertDataBoxPointBlock()



...



And that is probably where the issue is.



If you don't want to post the entire code, post the specific AutoCAD interactions...



--



http://cupocadnet.blogspot.com
Message 10 of 13
Anonymous
in reply to: Anonymous

Thanks, Bertvan.

I've attached the InsertDataPointBlock method and the Databox class. I've removed most of the methods that have no AutoCAD interaction.

I appreciate all of the help.
Stephen
Message 11 of 13
Anonymous
in reply to: Anonymous

My experience is, although simple, is a locked document somewhere which did not get unlocked?

Just thought I would toss in something that might help.
Message 12 of 13
Anonymous
in reply to: Anonymous

I don't think I locked any documents in this case. Can this be implicitly done? And if so, how? Then the question becomes how do you unlock a document?

Thanks,
Stephen
Message 13 of 13
Anonymous
in reply to: Anonymous

You don't need to lock the document if your code is called from
the handler of a registered command (that does not use the
CommandFlags.Session flag).

The LockDocument() method of the Document locks the
document, and disposing the object it returns unlocks the
document.

--
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


wrote in message news:6138680@discussion.autodesk.com...
I don't think I locked any documents in this case. Can this be implicitly
done? And if so, how? Then the question becomes how do you unlock a
document? Thanks, Stephen

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