無法獲取ADO.NET Dataset內存_.Net教程
推薦:ASP.NET 2.0控件異步回調雖然已經有了ASP.NET AJAX了,最近學習ASP.NET控件的時候,逐步理解了原始的控件異步回調(代碼取自《ASP.NET 2.0 高級編程》): 首先,在Render事件中添加好一個事件。 protected override void RenderContents(HtmlTextWriter output) { output.RenderBeg
無法獲取ADO.NET Dataset內存,Dataset是ADO.NET在內存保存數據所用的新結構。在某些方面上,Dataset和ADO的Recordset對象相似;不過,Dataset可以把整個schema(包括table、關系、關鍵字連同真實數據)保存在內存中,在這一點上,Dataset比Recordset功能更強。因此,你可以查詢和修改Dataset而不必擔心影響到正在使用它的數據庫。
當考慮到Dataset把它的全部數據放在內存中,有些人會擔心如果內存耗盡了會出現什么問題。做一個合理的猜測很容易,但是實際情況可能要比你猜測的要復雜一些。為了演示一下.NET在這種情況下會有什么動作,我先說說如何建立一個不停向一個Dataset中載入數據直到內存耗盡的項目。注意我們并不推薦這個過程,只是向你證明耗盡內存是多么容易的一件事。
建立TooMuchData項目
建立一個不停地向一個Dataset載入數據的項目很容易。打開Visual Studio .NET并創建一個新的VB.NET窗口應用程序。向視窗(form)中添加一個按鈕控件并雙擊它,這樣就開打了它的代碼窗口。在代碼窗口中填寫下列代碼:
Private Sub Button1_Click(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles Button1.ClickDim sConnString As String = "Server=localhost;Database=pubs;uid=sa;pwd=;"Dim sSQL As String = "SELECT * FROM authors"Dim daProduct As SqlDataAdapter = New SqlDataAdapter(sSQL, sConnString)Dim myDS As New DataSet()Do While TruedaProduct.Fill(myDS, "authors")If myDS.Tables("authors").Rows.Count Mod 100 = 0 ThenDebug.WriteLine(myDS.Tables("authors").Rows.Count.ToString())End IfLoopEnd Sub
代碼的第三行建立字符串到變量sConnString的聯接。如果你想重新建立這個項目,你或許需要修改這一行的代碼,除非你在服務器上運行它并有一個"sa/no password"用戶ID和相應的口令。
代碼的第四行建立一個簡單的SQL查詢。一般不推薦Select *這樣的用法,但是這里沒有什么問題,因為我們的目標就是抓到盡可能多的記錄。選擇的表格(table)的首要(primary)關鍵字域也不是問題,因為我們創建的Dataset是weakly type而且用來載入數據的DataTable的首要關鍵字域也沒有設置。
下兩行代碼創建DataAdapter和Dataset對象。然后進入一個死循環,在死循環中調用DataAdapter的Fill方法并把記錄加入稱之為“authors”的DataTable中。循環包括一個If語句用來顯示行數的當前值是否可以被100整除。這不是不必可少的,但是它可以有兩個方面的作用:首先,你可以知道程序依然在運行;其次,你可以知道大概有多少個記錄加到Dataset中去了。
運行本程序
當你建立本程序后,你可能希望在運行它之前作些修改。當Dataset越來越大時,它將消耗越來越多的內存。一旦它耗盡所有可用內存,Windows就開始把內存交換到內存交換文件中。在許多機器上,交換文件是相當大的,所以本程序可能要運行好幾個小時。例如,我在測試本程序時,用的是600-MHz PIII CPU和512-MB RAM的筆記本電腦。頁交換文件設置為最小值以縮短程序運行時間——這是盡快完成測試的訣竅。即使這樣,本程序在塞滿所有的可用內存之前還是運行了幾十分鐘或者若干小時。
現在你可以運行本程序并點擊按鈕控件來開始處理過程。它建立了一個到服務器的聯接,從表格中讀取數據并傳到Dataset中的DataTable對象。同樣的記錄也保存到該Dataset直到內存最終耗盡。你可以通過任務管理器來觀察內存的使用情況,你甚至可以看到可用內存的隨著內存和磁盤的數據交換而增減的情況。在我的機器中,Dataset在機器耗盡內存前已經長到1400000條記錄的規模。
耗盡內存
一旦你耗盡內存后會發生什么取決你是在VS.NET環境下運行本程序還是運行本程序的編譯版。如果你運行的是本程序的編譯版并且沒有進行錯誤處理(error handling),你在程序運行中不會發現錯誤,它僅僅是在內存耗盡時停止運行。如果你在VS.NET環境下運行代碼并且沒有進行錯誤處理,程序將會停止運行并在調試窗口下出現下面的錯誤信息:
Fatal out of memory error.
The program '[2340] TooMuchData.exe' has exited with code 0 (0x0).
因此,你可能會開始嘗試添加一個錯誤處理函數來檢測System.OutOfMemoryException的情況。例如,你可能用一個Try…Catch語句來觀察是否出現例外。一個比較通用的方法如下:
Do While TrueTrydaProduct.Fill(myDS, "authors")If myDS.Tables("authors").Rows.Count Mod 100 = 0 ThenDebug.WriteLine(myDS.Tables("authors").Rows.Count.ToString())End IfCatch ex As ExceptionMessageBox.Show("Error: " & ex.Message)End TryLoop
不幸的是,這種方法根本就不工作。在MessageBox.Show語句上設置一個斷點,理論上當運行到這個語句上應該出現,但是這一點永遠也不會到達。當最終耗盡內存時,調試窗口出現的卻是下面的信息:
Fatal out of memory error.
An unhandled exception of type 'System.OutOfMemoryException' occurred in system.data.dll
如果是MessageBox出現該消息情況會好些,但是相反,VS.NET(或者Framework)產生并顯示了上述消息,跟蹤這個特定的錯誤并不是有效的解決方法。
如果在本程序中添加錯誤處理并編譯運行它,那么你將得到另外一種結果。這次,你會發現MessageBox報告說程序遇到了一個無法處理的錯誤,類型為System.OutOfMemoryException,位于system.data.dll。然而,這個MessageBox來自Framework而不是你自己用代碼編寫的MessageBox。
并不象聽起來那么容易
你可以建立一個可以消耗所有可用內存的Dataset,但是消耗的過程并不簡單,它需要大量的記錄,尤其是大量的時間。Dataset可能需要幾個小時才能填滿內存,幾乎沒有什么應用程序可以在這種情況下運行很長時間,這就產生了問題。當然,每臺機器的配置都不盡相同,如處理器速度、內存容量以及交換文件大小,但是這種結果的出現都是不受歡迎的。
無論這種結果是如何令人討厭,錯誤都應該可以被捕獲。不幸的是,我們在這種情況下無法捕獲到System.OutOfMemoryException錯誤,也就是說我們在應用程序中很難處理這種特定錯誤。
分享:ASP.NET 2.0中使用OWC生成圖表ASP.NET 2.0中,要顯示圖型的話,可以用MS office 2003的OWC組件,可以十分方便地看到圖表。在工程中,首先添加microsoft office web components 11.0的引用就可以了,然后要using Microsoft.Office.Interop.Owc11; 1、生成柱狀圖 //創建X坐標的值,表示月份
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發送Email實例(可帶附件)
- js實現廣告漂浮效果的小例子
- asp.net Repeater 數據綁定的具體實現
- Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數據庫(連接字符串的配置及獲取)
- asp.net頁面傳值測試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現分頁示例代碼
- 相關鏈接:
- 教程說明:
.Net教程-無法獲取ADO.NET Dataset內存。