2011-06-30 263 views
3

我已經使用了多個線程之間共享的靜態Global數據集。DataTable內部索引已損壞:'5。在線程中使用

我得到了以下情況例外:

數據表內的索引是 損壞: '5'。

在線程,我讀從數據表&更新(用於合併)值在線程中完成兩個數據表的操作價值。

+0

你能張貼你的代碼嗎?以及哪條線路會產生錯誤? –

+0

你使用的是什麼.net框架? –

回答

2

您正在對來自不同線程的數據集進行操作。

該數據集不是線程安全的,您應該創建一個wrapper class,該數據集當時可以保護數據集不受多於1個操作的影響。這就是所謂的互斥:

link to microsoft msdn

一個更好的解決方案是沒有用的全局狀態可言。這將解決您的問題,無需任何額外的工作,並使您的代碼更可靠。

0

嗯,因爲你在多線程中使用你的dataTable,所以腐敗的可能性很高 - 如果你是從不同線程操縱對象的話。

一些幫助您解決問題:

  • 避免使用默認視圖,並 如果 可以修改默認視圖。順便說一句,.Net 2.0在創建 視圖時具有讀寫器鎖的號碼 ,因此它們不是 在2.0之前的問題。
  • 儘可能地調用AcceptChanges()。
  • 要小心。選擇(表達), 因爲沒有讀/寫鎖 在此代碼 - 這是(至少根據對新聞組的人 所以把它瓦特/只 地方一粒鹽的 - 然而,這是非常 類似於您的問題 - 因此使用 互斥可以幫助)
  • 設置AllowDBNull爲列 問題(有問題的價值,但 報道在新聞組 - 我已使用 它只在它使 有意義的地方)
  • 確保您沒有將 null(C#)/ Nothing(VB)設置爲DataRow 字段。使用DBNull.Value而不是 null。在您的情況下,您可能希望 檢查該字段不爲空,則 表達式語法確實支持 IsNull(val,alt_val)運算符。
  • 這可能幫助我最 (荒謬,因爲它聽起來):如果值是 不改變,不要分配它。例如,如果你想要的值賦給一些列做得一樣:
if (column.Expression != "some expression") 
     column.Expression = "some expression"; 

答案來源:StackOverflow - DataTable internal index is corrupted

0

這是我固定我的內部索引損壞問題:

System.Data.DataTable dtNew = new DataTable(); 
for (int iCol = 0; iCol < dtOriginalData.Columns.Count; iCol++) 
{ 
    dtNew.Columns.Add(dtOriginalData.Columns[iCol].ColumnName, dtOriginalData.Columns[iCol].DataType); 
} 
for (int iCopyIndex = 0; iCopyIndex < item.Data.Rows.Count; iCopyIndex++) 
{ 
    dtNew.Rows.Add(dtOriginalData.Rows[iCopyIndex].ItemArray); 
    //dtNew.ImportRow(dtOriginalData.Rows[iCopyIndex]); 
} 
dtOriginalData = dtNew; 
0

可能你在同一時間在多個進程中使用相同的數據表..我剛剛使用SYNCLOCK解決了這個問題..

試試這個..

SyncLock your datatable 

'''' -------your datatable process 

End SyncLock 

請讓我知道這對你有幫助..

編碼愉快..

0

爲了防止在執行多線程我用:

Application.Lock(); 
--- do your stuff in the datatable 
Application.UnLock(); 
1

如果您正在使用線程與數據集,則會發生該錯誤。

就我而言,我試圖在線程中運行的方法中爲數據集創建一個新行。

一種方法是使用SyncLock圍繞創建行或其他方式(甚至可能更好)的方法是在線程之外創建行。

基本上我的代碼看起來是這樣的:

Dim elements As New List(Of element) 
    Dim dataRows As New List(Of MyDataSet.Row) 

    For i As Integer = 0 To elements.Count - 1 
     dataRows.Add(Me.Ds.Elements.NewElementsRow) 
    Next 

    Parallel.For(0, elements.Count, Sub(i As Integer) 
             Me.CreateElementRow(elements(i), dataRows(i)) 
            End Sub) 

CreateElementRow方法,我做了很多計算的線程。

希望這會有所幫助。

0
DataTable.BeginLoadData(); 

// Do MultiThreaded Inserts 

DataTable.EndLoadData(); 
DataTable.AcceptChanges(); 

這將解決您的問題