最近,Winform程序在极其偶然的状况下会遇到以下错误提示数组
Framework 版本: v4.0.30319 说明: 因为未经处理的异常,进程终止。 异常信息: System.InvalidOperationException 堆栈: 在 System.Data.RBTree`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].RBDeleteX(Int32, Int32, Int32) 在 System.Data.RBTree`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].DeleteByIndex(Int32) 在 System.Data.Index.RecordStateChanged(Int32, System.Data.DataViewRowState, System.Data.DataViewRowState, Int32, System.Data.DataViewRowState, System.Data.DataViewRowState) 在 System.Data.DataTable.RecordStateChanged(Int32, System.Data.DataViewRowState, System.Data.DataViewRowState, Int32, System.Data.DataViewRowState, System.Data.DataViewRowState) 在 System.Data.DataTable.SetNewRecordWorker(System.Data.DataRow, Int32, System.Data.DataRowAction, Boolean, Boolean, Int32, Boolean, System.Exception ByRef) 在 System.Data.DataTable.SetNewRecord(System.Data.DataRow, Int32, System.Data.DataRowAction, Boolean, Boolean, Boolean) 在 System.Data.DataRow.EndEdit() 在 System.Data.DataRow.set_Item(System.Data.DataColumn, System.Object)
相信有很多人遇到过这个问题,老王也被这个问题困扰了一个星期了。安全
差了很多资料,此问题基本与版本无关,由于1.0、1.一、2.0、3.五、4.0、4.5都是能够重现问题的。多线程
来看一下调用堆栈,若是你看到DataView.OnListChanged,你正在更改一个DataRow/Set/Table,这时极可能会发生索引损坏(即被DataRow.EndEdit抛出)。.net
简短描述一下这个问题:内部索引获得编辑out-of-order的消息。线程
解决方法-使用DataTable.RowChanged事件,而不是DataView.ListChanged事件。orm
当 LoadOption.PreserveChanges事件发生时,调用DataAdapter.Fill, DataSet.Load, DataTable.Load事件。对象
用DataSet.Merge, DataTable.Merge来删除行。blog
用DataSet.Merge (DataRow[])添加行。排序
简单描述问题:当DataTable让DataView “添加”而不是“修改”时,致使索引损坏。索引
DataSet/ DataTable和任何链接的对象都不是线程安全的。请确保您锁定全部合适的对象。
个人问题属于此类,由于我在多线程中都有操做DataTable,而后,看了这篇帖子,我在全部操做DataTable的地方都加入了Lock语句,而后问题解决了!
感谢此文做者 GR_king,原文网址:http://blog.51cto.com/gleolee/1911134
lock (datatable) { 针对datatable的操做 }
例如:DataColumn.DataType是byte []类型和按照列排序的。若是在byte数组中的值改变而不是制定一个新的byte数组给DataRow,
那么内部的索引不知道这样的变化,而后损坏。这是在没有通知内部索引的状况下数据发生改变。
本文非原创,转自:https://blog.csdn.net/deboywang/article/details/84070501