"DataTable internal index is corrupted" - what's that?

  • Thread starter Dzianis Davydzenka
  • Start date
D

Dzianis Davydzenka

Hi there.

I have a multithread application which handles pretty huge (~130000 records)
dataset. Each thread gets record to handle, make some modification to its
fields and gets next record. After all links have been modified main thread
updates DB - simple actions.

Now I have a problem - after some records have been processed (may be 1000,
may be 100000) app throws an exception as in subject. Here is a code, which
leads to crash:

string strOldStatus = String.Empty;
if (oRequestState.Row["InvalidCode"] == DBNull.Value ||
Convert.ToInt32(oRequestState.Row["InvalidCode"]) != (int)status)
{
oRequestState.Row["InvalidCode"] = (int)status;
if (!IsStatusOK(status))
oRequestState.Row["URL_Title"] = String.Empty;
}
oRequestState.Row["Last_Verified"] = DateTime.Now;
strOldStatus = (oRequestState.Row["InvalidCode", DataRowVersion.Original] ==
DBNull.Value) ? String.Empty :
_ds.Statuses[(byte)oRequestState.Row["InvalidCode",
DataRowVersion.Original]].ToString();

where oRequestState.Row is a DataRow, _ds.Statuses is a Hashtable. There is
a relation in dataset of oRequestState.Row, but that relation is not on
fields used in code snippet above. Relation is constructed before processing
all the records.

Here is a stacktrace:

05/02 14:04:33 [2220] HTTPRequester - Error in ProcessRequests: DataTable
internal index is corrupted: '5'.
Stack: at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32
position)
at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32
position)
at System.Data.Index.RecordStateChanged(Int32 oldRecord, DataViewRowState
oldOldState, DataViewRowState oldNewState, Int32 newRecord, DataViewRowState
newOldState, DataViewRowState newNewState)
at System.Data.DataTable.RecordStateChanged(Int32 record1,
DataViewRowState oldState1, DataViewRowState newState1, Int32 record2,
DataViewRowState oldState2, DataViewRowState newState2)
at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32
proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position,
Boolean fireEvent)
at System.Data.DataRow.EndEdit()
at System.Data.DataRow.set_Item(DataColumn column, Object value)
at System.Data.DataRow.set_Item(String columnName, Object value)
at HTTPTest.HTTPRequester.ProcessRequests()

So I can't guess what leads to such exception after some minutes or hours of
application work??? Additionaly after such exception had been thrown other
app threads begin to throw "Index was outside the bounds of the array"
exception on the same piece of code. Then stacktrace is as follows:

05/02 14:05:54 [1032] HTTPRequester - Error in ProcessRequests: Index was
outside the bounds of the array.
Stack: at System.Data.RecordManager.NewRecordBase()
at System.Data.DataTable.NewRecord(Int32 sourceRecord)
at System.Data.DataRow.BeginEditInternal()
at System.Data.DataRow.set_Item(DataColumn column, Object value)
at System.Data.DataRow.set_Item(String columnName, Object value)
at HTTPTest.HTTPRequester.ProcessRequests()

Can anybody shed a light on this issue? Would very appreciate that.
 
D

Dzianis Davydzenka

Seems like I found solution for this issue: before updating row's values
need to call DataRow.BeginEdit() and call DataRow.EndEdit() after all
changes are made.

Looks like ADO.Net modifies column values implicitly calling .BeginEdit()
and .EndEdit() BUT when there are several threads running simultaneously and
accessing DataTable ADO.Net do not synchronize those write operations.

But now I fall into another issue: when all data was edited I try to update
DB (via SP) and get following exception:

"SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999
11:59:59 PM". I have DateTime field inside DataSet table.

That is the code I use to create parameter for update SP:

sqlUpdCmd.Parameters.Add(new SqlParameter("@Last_Verified",
SqlDbType.DateTime, 8, "Last_Verified"));

Does anybody know what's wrong with update I'm trying to accomplish?


Dzianis Davydzenka said:
Hi there.

I have a multithread application which handles pretty huge (~130000
records) dataset. Each thread gets record to handle, make some
modification to its fields and gets next record. After all links have been
modified main thread updates DB - simple actions.

Now I have a problem - after some records have been processed (may be
1000, may be 100000) app throws an exception as in subject. Here is a
code, which leads to crash:

string strOldStatus = String.Empty;
if (oRequestState.Row["InvalidCode"] == DBNull.Value ||
Convert.ToInt32(oRequestState.Row["InvalidCode"]) != (int)status)
{
oRequestState.Row["InvalidCode"] = (int)status;
if (!IsStatusOK(status))
oRequestState.Row["URL_Title"] = String.Empty;
}
oRequestState.Row["Last_Verified"] = DateTime.Now;
strOldStatus = (oRequestState.Row["InvalidCode", DataRowVersion.Original]
== DBNull.Value) ? String.Empty :
_ds.Statuses[(byte)oRequestState.Row["InvalidCode",
DataRowVersion.Original]].ToString();

where oRequestState.Row is a DataRow, _ds.Statuses is a Hashtable. There
is a relation in dataset of oRequestState.Row, but that relation is not on
fields used in code snippet above. Relation is constructed before
processing all the records.

Here is a stacktrace:

05/02 14:04:33 [2220] HTTPRequester - Error in ProcessRequests: DataTable
internal index is corrupted: '5'.
Stack: at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id,
Int32 position)
at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32
position)
at System.Data.Index.RecordStateChanged(Int32 oldRecord,
DataViewRowState oldOldState, DataViewRowState oldNewState, Int32
newRecord, DataViewRowState newOldState, DataViewRowState newNewState)
at System.Data.DataTable.RecordStateChanged(Int32 record1,
DataViewRowState oldState1, DataViewRowState newState1, Int32 record2,
DataViewRowState oldState2, DataViewRowState newState2)
at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32
proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position,
Boolean fireEvent)
at System.Data.DataRow.EndEdit()
at System.Data.DataRow.set_Item(DataColumn column, Object value)
at System.Data.DataRow.set_Item(String columnName, Object value)
at HTTPTest.HTTPRequester.ProcessRequests()

So I can't guess what leads to such exception after some minutes or hours
of application work??? Additionaly after such exception had been thrown
other app threads begin to throw "Index was outside the bounds of the
array" exception on the same piece of code. Then stacktrace is as follows:

05/02 14:05:54 [1032] HTTPRequester - Error in ProcessRequests: Index was
outside the bounds of the array.
Stack: at System.Data.RecordManager.NewRecordBase()
at System.Data.DataTable.NewRecord(Int32 sourceRecord)
at System.Data.DataRow.BeginEditInternal()
at System.Data.DataRow.set_Item(DataColumn column, Object value)
at System.Data.DataRow.set_Item(String columnName, Object value)
at HTTPTest.HTTPRequester.ProcessRequests()

Can anybody shed a light on this issue? Would very appreciate that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top