我正在使用C#中的.NET WinForms应用程序,针对3.5 .NET框架运行。在这个程序,我设置一个DataColumn
的.Expression成员在DataTable
,像这样:DataTable内部索引已损坏
DataColumn column = dtData.Columns["TestColumn"];
column.Expression = "some expression";
第二行,在那里我居然设置Expression
,有时会导致以下异常:
FileName=
LineNumber=0
Source=System.Data
TargetSite=Int32 RBInsert(Int32, Int32, Int32, Int32, Boolean)
System.InvalidOperationException: DataTable internal index is corrupted: '5'.
at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32 mainTreeNodeID, Int32 position, Boolean append)
at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32 mainTreeNodeID, Int32 position, Boolean append)
at System.Data.Index.InitRecords(IFilter filter)
at System.Data.Index.Reset()
at System.Data.DataTable.ResetInternalIndexes(DataColumn column)
at System.Data.DataTable.EvaluateExpressions(DataColumn column)
at System.Data.DataColumn.set_Expression(String value)
关于错误何时会发生,没有可察觉的押韵或原因;在加载相同的数据集时,它可能正常工作,但重新加载将失败,反之亦然。这让我认为它与竞争条件有关,在DataTable
上发生另一个写入操作,因为我试图修改其中的一列。但是,与DataTable
有关的代码是而不是多线程并且只在UI线程上运行。
我搜查了网页和Microsoft forums,并且在这个问题上有很多讨论和混淆。回到2006年第一次报道该问题时,人们认为这是.NET框架中的一个缺陷,并且发布了一些推测的修补程序,这些修补程序大概会推出到.NET框架的更高版本中。但是,人们在应用那些不再适用于当前框架的修补程序时报告了各种各样的结果。
另一个流行的理论是DataTable上有操作,尽管看起来无害,但它实际上是写操作。例如,基于DataTable
创建新的DataView
实际上是对表本身的写操作,因为它在DataTable
中创建了一个内部索引供以后参考。这些写入操作不是线程安全的,所以有时会发生竞态条件导致与我们访问DataTable
相同的无线安全写入。这反过来会导致DataTable
的内部索引损坏,导致例外。
我试图把lock
块左右各DataView
创作中的代码,但是,正如我前面提到,利用DataTable
不是线程代码,和lock
小号都没有效果,在任何情况下。
有没有人看过这个,并成功解决/解决它?
不,不幸的是我不能。加载DataTable的时候已经发生了,当我将它保存到一个DataColumn的表达式中。我可以删除列,然后重新添加它使用您建议的代码,但是有一个特定的原因,为什么这将解决内部索引已损坏的问题?
实际是什么“有些表达”?你是否遵循http://tinyurl.com/7tj8av中的命名惯例? – balexandre 2009-01-16 20:37:40
我遇到了同样的错误,这是修复它对我来说:[StackOverflow - 内部索引已损坏](http://stackoverflow.com/a/34154179/3119607) – mrc 2015-12-08 11:09:37
此错误为我尝试时对数据集运行选择查询。它发生在搜索那里的东西时,并没有发现时,搜索的东西不是。我意识到当我创建一个新的数据行并添加它时,我没有锁定表,直到我将该行添加到表的最后一步。实际上,当我声明新行时不得不锁定它,直到将它添加到表中之后才释放锁。这与我发现错误的代码完全不同。 – Grungondola 2016-04-25 20:38:46