数据表的内部索引已损坏数据表、索引

2023-09-02 20:45:29 作者:裀伱而沈淪づ

我的工作在C#.NET程序WinForms应用程序,对.NET 3.5框架运行。在这个程序,我设置了一个的DataColumn 数据表,像这样的.EX pression成员

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

第二行,在那里我居然设置防爆pression ,有时会导致以下异常:

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)

没有察觉没头没脑至于何时会发生的错误;在加载相同的数据集,它可能工作正常,但随后重新加载它会失败,反之亦然。这使我认为这是关系到一个竞争条件,在另一次写操作发生在数据表因为我试图修改其列。但是,与数据表 S中的code是的没有的多线程,运行仅在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框架中的缺陷,并有发布了一些假想的修复程序是presumably滚入更高版本的.NET Framework。然而,人们报告好坏参半的结果在应用这些修补程序,这已经不再适用于目前的框架。

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.

另外prevailing理论是,有在数据表这虽然看似无害,其实是写操作操作。例如,创建一个新的数据视图一个基于数据表实际上是对表本身的写操作,因为它创建在数据表供以后参考的内部指标。这些写操作不是线程安全的,所以有时会发生竞争状态导致了无螺纹安全写入与我们的数据表的访问恰逢。这反过来,使数据表的内部索引被损坏,从而导致异常。

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.

我试图把周围每个数据视图创作中的code 锁定块,但正如我前面所提到的,code利用数据表没有螺纹,而锁定取值都没有效果,在任何案例。

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?

没有,遗憾的是我不能。加载数据表已经发生的时候,我得到了保持它适用防爆pression到它的DataColumn的之一。我可以删除列,然后使用code您建议重新添加,但有一个特别的原因,将解决内部索引损坏问题?

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 并重新添加后,我与数据表进行

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:还没定......除了不断攀升的所有不同的地方在我的code自上周四以来...这是迄今为止最奇怪,最滚泥*荷兰国际集团的错误我已经在框架中遇到到目前为止,(我已经在3年里,我一直在与.NET 2.0见过很多奇怪的事情,足以保证不会对我将来的项目单将建立在它)。但足够的咆哮,回到话题。

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.

我已经通过整个讨论在微软支持论坛,然后我给你的是一个简要的总结。原来的错误报告起源于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:的的Bug报告第一次调查开始。纵观明年当然报道以不同的形式和不同的表现形式。 的 三月'07:的最后的与数KB 932491 修补程序被释放(不明白你的希望),它把对的下载一个完全不相干的寻找修复的,或者至少看起来是这样的。纵观接下来的几个月,许多报告指出,修补程序不能正常工作,有些报告成功。 的 七月'07:的活微软过去的标志(一个完整的无用的答案),超过该点是微软没有进一步回应。没有进一步的确认,对支持否尝试,以获取更多信息......没有没有请求。除了这一点有唯一的社区相关的信息。 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:

数据表是不可以线程安全的。你必须锁定 / 同步你自己,如果你有多线程上的任何地方。 在该指数的腐败发生的地方之前实际抛出异常。 在一个可能的腐败根源或者是一个应用防爆pression 或适用排序。 另一个可能的来源是 DataTable.ListChanged()事件,也从来没有修改数据,该事件或派生的任何事件。这包括绑定控件不同的更改事件。 在有约束力的,当默认视图对控制有可能的问题。始终使用 DataTable.BeginLoadData() DataTable.EndLoadData()。 创建和操作的默认视图是写操作在数据表(和首页),飞行面条怪物知道这是为什么。 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.

这样做的可能的来源是最有可能的竞争条件,无论是在我们的源$ C ​​$ C或框架的code。因为它似乎,微软是无法修复这个bug或无意。无论哪种方式,检查你的code的竞争条件,它有事可做与默认视图在我看来。在某一点上的插入或操纵数据被破坏的内部指标,因为更改不正确贯穿全 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; ),并重新添加数据的装载完成之后。其中燃料我的想法,它有事可做与默认视图,并从绑定控件它酿出的事件。

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.