2011-10-19 46 views
0

我正在使用Compact Framework中的.NET DataSets。一個DataSet包含四個或五個表,其中包含輕量數據(每行幾行)。主數據表(所有外鍵約束所基於的)都包含一行。 DataSet作爲XML文件(使用DataSet.WriteXML)持久化到磁盤。.NET(CF)DataRow如何自發地將所有值設置爲DBNull?

我們的發現是,每隔一段時間,DataRow中的價值觀都得到設定的DBNull沒有明顯的原因。更重要的是,當數據再次持續存在時,主數據表的單行將被寫入而沒有數據。

例如,我們希望看到:

<MyDataSet> 
<MyTypedDataRow id="1" data1="data" data2="more data" /> 
... 

其中「數據1」和「數據2」都是非空列。相反,我們很少得到:

<MyDataSet> 
<MyTypedDataRow /> 
... 

這應該是不可能的。

我們的環境確實使用了多線程,但進入到DataSet在很大程度上線程把守。

當我試圖在調試器中發生這種情況時,由於表的約束,我所有的努力都會遇到錯誤。

有沒有人對如何這可能發生的任何想法?

感謝您的期待。


編輯:有一件事我沒有提及哪一個可能是一個促成因素。這是一個強類型數據集是使用Visual Studio設計製造,但在創建之後已經發生了顯著手動修改(不要怪我,這是我的時間之前)。顯然,這可能會產生一系列意想不到的副作用......但即使我們嘗試了,我也看不出這個問題會如何發生。

+0

您的設備是否在這些錯誤之間睡眠?也許它......失去它不知何故從睡夢中醒來。 (???) – jp2code

+0

不,我不認爲就是這樣(但感謝這個建議;在這一點上,我正在尋找我沒有想到的任何想法)。我們的設備連續運行,並沒有進入任何類型的睡眠。有趣的是,我們的應用程序日誌清楚地顯示數據集最後一次修改(成功),然後保存...然後8秒鐘後,當應用程序嘗試訪問同一行中的其他數據時會報告「InvalidCastException」剛剛修改。儘管我們已經投入了線程防護,但我願意相信這是一個線程問題......但我看不出如何。 – Greenknight

回答

0

這肯定是bizaare,和我想像別的東西很可能繼續。

爲了幫助您測試,我建議接線一些事件處理程序,你可以檢查。

這裏是一個測試類,你可以使用它適用於WM5和CF 2.0。

查看當你的數據丟失時發生了什麼。

class TestOnly { 

    public DataTable Table { get; set; } 

    public TestOnly() { 
    Table = new DataTable(); 
    Table.Disposed += new EventHandler(Table_Disposed); 
    Table.ColumnChanging += new DataColumnChangeEventHandler(Table_ColumnChanging); 
    Table.RowChanging += new DataRowChangeEventHandler(Table_RowChanging); 
    Table.RowDeleting += new DataRowChangeEventHandler(Table_RowDeleting); 
    Table.TableClearing += new DataTableClearEventHandler(Table_TableClearing); 
    } 

    bool myAct = false; 

    void Table_TableClearing(object sender, DataTableClearEventArgs e) { 
    Console.WriteLine("Table {0} clearing. {1}", e.TableName, DateTime.Now); 
    } 

    void Table_ColumnChanging(object sender, DataColumnChangeEventArgs e) { 
    if (!myAct) { 
     e.Row.CancelEdit(); 
     Console.WriteLine("Edit of {0} cancelled. {1}", e.Column.Caption, DateTime.Now); 
    } 
    } 

    void Table_RowChanging(object sender, DataRowChangeEventArgs e) { 
    if (!myAct) { 
     e.Row.CancelEdit(); 
     Console.WriteLine("DataRow Action {0} cancelled. {2}", e.Action, DateTime.Now); 
    } 
    } 

    void Table_RowDeleting(object sender, DataRowChangeEventArgs e) { 
    if (!myAct) { 
     e.Row.CancelEdit(); 
     Console.WriteLine("DataRow Action {0} cancelled. {2}", e.Action, DateTime.Now); 
    } 
    } 

    void Table_Disposed(object sender, EventArgs e) { 
    Console.WriteLine("Table Disposed at {0}.", DateTime.Now); 
    } 


} 
0

我已經發現了更多關於這個問題,我認爲將解決我的問題。

我創建了一個包含設計器構建的強類型DataSet的簡單測試應用程序。該應用程序在啓動時產生三個線程。兩個修改同一列中的值,然後讀取值,並重復廣告無限。第三個線程將DataSet連續保存到磁盤。

最終(在幾秒到一分鐘的範圍內),線程提起DataSet,這樣它就會拋出一個帶有文本的異常:「DataTable內部索引已損壞:5」。如果我繼續吞下這些異常,最終會遇到「InvalidCastException」,因爲它是DBNull,所以無法從該行讀取數據。當發生這種情況時,我可以看到整行是DBNull,甚至是主鍵。

有趣的是,「WriteXML」方法不是在此狀態下拋出異常;該文件可以以這種方式保存,即使它違反了所有約束條件。

在我的實際應用中,我認爲我的線程防護在這個區域周圍是不夠的。我不知道這是ADO.NET的內部錯誤,還是ADO.NET對象的良好線程防護的參數。無論哪種方式,這是一個非常惱人的問題。

相關問題