DataTable 内部索引损坏 [英] DataTable internal index is corrupted

查看:89
本文介绍了DataTable 内部索引损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 C# 中的 .NET WinForms 应用程序,在 3.5 .NET 框架上运行.在这个应用程序中,我在 DataTable 中设置 DataColumn 的 .Expression 成员,如下所示:

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 DataTable, like so:

DataColumn column = dtData.Columns["TestColumn"];
column.Expression = "some expression";

第二行,我实际设置的Expression,有时会导致以下异常:

The 2nd line, where I actually set Expression, will sometimes result in the following exception:

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 上发生了另一个写操作.但是,与DataTables 相关的代码不是多线程的,只在UI线程上运行.

There is no perceptible rhyme or reason as to when the error will occur; in loading the same data set, it may work fine but then reloading it will fail, and vice versa. This leads me to think it is related to a race condition, where another write operation is occurring on the DataTable as I'm trying to modify one of its columns. However, the code relating to DataTables is not multi-threaded and runs only on the UI thread.

我在网上搜索过,Microsoft 论坛,关于这个问题有很多讨论和混淆.早在 2006 年首次报告该问题时,人们就认为这是 .NET 框架中的一个缺陷,并且发布了一些假定的修补程序,这些修补程序可能已被纳入到 .NET 框架的更高版本中.但是,人们在应用这些修补程序时报告了不同的结果,这些修补程序不再适用于当前框架.

I have searched the web and Microsoft forums, and there is much discussion and confusion over this issue. Back when the issue was first reported in 2006, the thought was that it was an flaw in the .NET framework, and there were some supposed hotfixes released that were presumably rolled into later versions of the .NET framework. However, people have reported mixed results in applying those hotfixes, which are no longer applicable to the current framework.

另一个流行的理论是对 DataTable 进行了一些操作,虽然看似无害,但实际上是写操作.比如基于一个DataTable创建一个新的DataView其实就是对表本身的写操作,因为它在DataTable中创建了一个内部索引> 供以后参考.这些写入操作不是线程安全的,因此有时会发生竞争条件导致非线程安全写入与我们对 DataTable 的访问一致.这反过来会导致 DataTable 的内部索引损坏,从而导致异常.

Another prevailing theory is that there are operations on the DataTable which, though seemingly innocuous, are actually write operations. For example, creating a new DataView based on a DataTable is actually a write operation on the table itself, because it creates an internal index in the DataTable for later reference. These write operations are not thread-safe, so it sometimes happens that a race condition leads to an unthread-safe write coinciding with our access of the DataTable. This, in turn, causes the internal index of the DataTable to become corrupted, leading to the exception.

我尝试在代码中的每个 DataView 创建周围放置 lock 块,但是,正如我之前提到的,使用 DataTable 的代码是没有线程化,并且 locks 在任何情况下都不起作用.

I have tried putting lock blocks around each DataView creation in the code, but, as I mentioned before, code utilizing the DataTable is not threaded, and the locks had no effect, in any case.

有没有人看到这个并成功解决/解决了它?

Has anyone seen this and successfully solved / worked around it?

不,不幸的是我不能.当我掌握它以将表达式应用于其中一个 DataColumn 时,已经加载了 DataTable.我可以删除该列,然后使用您建议的代码重新添加它,但是是否有特殊原因可以解决内部索引损坏的问题?

No, unfortunately I can not. Loading the DataTable has already occurred by the time I get a hold of it to apply an Expression to one of its DataColumn's. I could remove the column and then re-add it using the code you suggested, but is there a particular reason why that would solve the internal index is corrupted problem?

推荐答案

我刚刚在导入行时遇到了同样的问题,似乎在插入之前调用了 DataTable.BeginLoadData 为我修复了它.

I just had the same issue while importing rows, as it seems, calling DataTable.BeginLoadData before the insert fixed it for me.

事实证明,这只在一侧修复了它,现在添加行会引发此异常.

As it turns out, this only fixed it on one side, now adding rows throws this exception.

Edit2: 按照 Robert 的建议暂停绑定Rossney 也为我解决了添加问题.我只是从 DataGridView 中删除了 DataSource 并在完成 DataTable 后阅读它.

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: 仍然没有修复......自周四以来,异常不断出现在我代码中的所有不同地方......这是迄今为止最奇怪和最糟糕的错误到目前为止,我已经在框架中遇到过(并且在我使用 .NET 2.0 的 3 年中我看到了许多奇怪的事情,足以保证我未来的任何项目都不会基于它构建).言归正传,言归正传.

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.

我已经阅读了整个讨论 在 Microsoft 支持论坛上,我会给您一个简短的摘要.原始 错误报告源自在'05.

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.

  • 06 年 3 月: 首次报告错误,调查开始.在接下来的一年中,它以不同的形式和不同的表现形式进行报告.
  • 07 年 3 月: 最后 发布了编号为 KB 932491 的修补程序(不要抱太大希望),它链接到 下载一个看起来完全不相关的修补程序,或者至少看起来是这样.在接下来的几个月里,许多人报告说修补程序不起作用,有些人报告说成功了.
  • 07 年 7 月: 微软的最后一个现场信号(带有一个完全无用的答案),除此之外,微软没有进一步的回应.没有进一步的确认,没有尝试支持,没有要求更多的信息.​​.....什么都没有.除此之外,只有社区相关信息.
  • March '06: Bug is reported the first time, investigation starts. Throughout the course of the next year it is reported in different forms and different manifestations.
  • March '07: Finally a hotfix with number KB 932491 is released (don't get your hopes up), it links against a download of an completely irrelevant looking hotfix, or at least so it seems. Throughout the next months many report that the hotfix does not work, some are reporting success.
  • July '07: Last sign of live from Microsoft (with a complete useless answer), beyond this point is no further response from Microsoft. No further confirmations, no attempts on support, no requests for more information...nothing. Beyond this point there's only community related information.

不严重,我认为这是总结.我能够从整个讨论中提取以下信息:

No seriously, this sums it up in my opinion. I was able to extract the following information from the whole discussion:

  • DataTable 不是线程安全的.如果你有多线程,你必须自己Lock/Synchronize.
  • 索引损坏发生在之前抛出实际异常.
  • 一个可能的损坏源是应用的 Expression 或应用的 Sort.
  • 另一个可能的来源是 DataTable.ListChanged() 事件,切勿修改此事件中的数据或任何由此产生的事件.这包括来自绑定控件的不同 Changed 事件.
  • DefaultView 绑定到控件时可能会出现问题.始终使用 DataTable.BeginLoadData()DataTable.EndLoadData().
  • DefaultView 的创建和操作是对DataTable(及其Index)的写入操作,飞行意大利面怪物知道为什么.
  • The DataTable is not Thread-Safe. You'll have to Lock/Synchronize it on your own if you have Multi-Threading anywhere on it.
  • The corruption of the index happens somewhere before the actual exception is thrown.
  • One possible corruption source is either an applied Expression or an applied Sort.
  • Another possible source is the 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.
  • There are possible issues when binding the DefaultView against a control. Always use DataTable.BeginLoadData() and DataTable.EndLoadData().
  • Creation and manipulation of the DefaultView is a writing operation on the DataTable (and its Index), the Flying Spaghetti Monster knows why.

这种情况的可能来源很可能是我们的源代码或框架代码中的竞争条件.看起来,Microsoft 无法或无意修复此错误.无论哪种方式,请检查您的代码是否存在竞争条件,在我看来,它与 DefaultView 有关系.在某些时候,Insert 或对数据的操作会破坏内部索引,因为更改未正确传播到整个 DataTable.

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:我能够通过完全删除绑定(control.DataSource = null;)并在加载数据后重新添加它来避免此错误完成了.这激发了我的想法,它与 DefaultView 和从绑定控件产生的事件有关.

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.

这篇关于DataTable 内部索引损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆