最近,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