I am working with a .NET WinForms app in C#, running against the 3.5 .NET framework. In this app, I am setting the .Expression member of a DataColumn
in a
I just had the same issue while importing rows, as it seems, calling DataTable.BeginLoadData
before the insert fixed it for me.
Edit: As it turns out, this only fixed it on one side, now adding rows throws this exception.
Edit2: Suspending binding as suggested by Robert Rossney fixed the adding problem for me, too. I simply removed the DataSource
from the DataGridView
and readded it after I was done with the DataTable
.
Edit3: Still not fixed...the exception keeps creeping up in all different places in my code since Thursday...this is by far the strangest and most f****ing bug I've encountered in the Framework so far (and I've seen many odd things in the 3 years I've been working with .NET 2.0, enough to warrant that not a single of my future projects will be build on it). But enough of ranting, back on topic.
I've read through the whole discussion at the Microsoft support forums and I'll give you a brief summary of it. The original bug report originates in '05.
No seriously, this sums it up in my opinion. I was able to extract the following information from the whole discussion:
DataTable
is not Thread-Safe. You'll have to Lock
/Synchronize
it on your own if you have Multi-Threading anywhere on it.Expression
or an applied Sort
.DataTable.ListChanged()
event, do never modify data in this event or any event which spawns from it. This includes different Changed
events from bound controls.DefaultView
against a control. Always use DataTable.BeginLoadData()
and DataTable.EndLoadData()
.DefaultView
is a writing operation on the DataTable
(and its Index
), the Flying Spaghetti Monster knows why.The possible source of this is most likely a race condition, either in our source code or in the code of the framework. As it seems, Microsoft is unable to fix this bug or has no intention to. Either way, check your code for race conditions, it has something to do with the DefaultView
in my opinion. At some point an Insert
or a manipulation of the data is corrupting the internal Index because the changes are not properly propagated through the whole DataTable
.
I'll of course report back when I find further informations or additional fixes. And sorry if I get a little bit emotional here, but I've spent three days trying to pinpoint this issue, and it slowly starts to look like a good reason to get a new job.
Edit4: I was able to avoid this bug by completely removing the binding (control.DataSource = null;
) and re-adding it after the loading of the data is completed. Which fuels my thought that it has something to do with the DefaultView
and the events which spawn from the bound controls.
The same happened to me too. Winforms, .NET 3.5, unexpectectly got this error trying to set one of the columns in typed row. Code was rather old and worked for a long time so it was kind of unpleasant surprise...
I needed to set new SortNo's in typed table TadaTable in dataset TadaSet.
What helped me, you can also try this:
int i = 0;
foreach (TadaSet.TadaTableRow row in source)
{
row.BeginEdit(); //kinda magical operation but it helped :)
// Also you can make EndEdit() for each row later if you need...
short newNo = i++;
if (newNo != row.SortNo) row.SortNo = newNo; //here was the crash
}
I had the same problem using Threads. What I did was create a delegate which is called when I need to merge the table.
internal delegate void MergeData (DataTable dataTable1, DataTable dataTable2);
internal static void MergeDataTable (DataTable dataTable1, DataTable dataTable2)
{
dataTable1.Merge (dataTable2, true);
}
Then during execution I call the delegate and the error does not occur.
Delegates.MergeData mergeData = new Delegates.MergeData (Delegates.MergeDataTable);
object [] paramsMerge = {dataTable1, dataTable2};
this.Invoke (mergeData, paramsMerge);
I resolved my datatable-internal-index error this way:
changed CellEndEdit
to CellBeginEdit
event. Also... avoid using NULLs unnecessarily:
Private Sub User_role_groupDataGridView_CellBeginEdit(sender As Object, e As DataGridViewCellCancelEventArgs) Handles User_role_groupDataGridView.CellBeginEdit
Try
If Not Me.User_role_groupDataGridView.Rows(e.RowIndex).IsNewRow Then Me.User_role_groupDataGridView.Rows(e.RowIndex).Cells("last_modified_user_group_role").Value = Now
Catch ex As Exception
Me.displayUserMessage(ex.ToString, Me.Text, True)
End Try
End Sub
I had the same issue (table index corrupted with 5) on adding rows programaticly to a dataset which is bound to the datagridview. I didn't take into account that there was an eventhandler on the AddRow event of the datagridview, which does some initialization in case the user starts the new row by UI. In exceptions stack trace nothing was seen of it. By disabling the event I could solve this fast. I came to it only by reading some comments here in deep. 2hours not too much for issues like that :-), I think. You can find this by setting breakpoint in every eventhandler assigned to datgridview which is linked to the dataset.
How about trying the idea of applying a mutex as described here to induce sleep in the thread in such conditions?