频 道 直 达 - 新闻 - 读书 - 培训 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 技术圈 - 博客 - BBS
51CTO.COM_中国领先的IT技术网站
找资料:

一个无法捕获ADO.NET Dataset的内存错误

作者: 出处:.NET文档  (  ) 砖  (  ) 好  评论 ( ) 条  进入论坛
更新时间:2006-12-26 15:14
关 键 词:.NET  ADO  Dataset  内存
阅读提示:Dataset是ADO.NET在内存保存数据所用的新结构。我们在本文中所讲的情况下无法捕获到System.OutOfMemoryException错误,也就是说我们在应用程序中很难处理这种特定错误。

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.Click
Dim 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 True
daProduct.Fill(myDS, "authors")
If myDS.Tables("authors").Rows.Count Mod 100 = 0 Then
Debug.WriteLine(myDS.Tables("authors").Rows.Count.ToString())
End If
Loop
End 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 True
Try
daProduct.Fill(myDS, "authors")
If myDS.Tables("authors").Rows.Count Mod 100 = 0 Then
Debug.WriteLine(myDS.Tables("authors").Rows.Count.ToString())
End If
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message)
End Try
Loop

不幸的是,这种方法根本就不工作。在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错误,也就是说我们在应用程序中很难处理这种特定错误。

(责任编辑 火凤凰 sunsj@51cto.com  TEL:(010)68476636-8007)


发表
查看
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 领 先 的 IT 技 术 网 站 ·
技 术 成 就 梦 想
·Java基础教程 (查看52473次)
·UML类图详解 (查看46951次)
·Java编程开发手册 (查看25172次)
·UML统一建模语言 (查看24155次)
·C#技术开发指南 (查看22515次)
·Java编程开发手册 (1195个砖)
·Java基础教程 (429个砖)
·C#技术开发指南 (304个砖)
·PB开发教程 (220个砖)
·.NET开发手册 (217个砖)
·Java编程开发手册 (653个好)
·Java基础教程 (569个好)
·.NET开发手册 (251个好)
·PB开发教程 (209个好)
·Delphi开发技术手册 (174个好)
订阅技术快讯
电子杂志下载
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
名称:Vista精品应用黄皮书
简介:《Vista精品应用黄皮书》囊括了Vista的各方面内容。此次的精简版,是将里面的内容做了提取,便于用户下载和使用。内容包含了各种Vista的安装与实施、技巧与解析以及各种Vista相关学习文档和相关软件的安全下载。该电子书是了解和应用Vista人员必备的工具手册,并且也是第一本
名称:2006中国IT论坛精品集合
简介:本书由“51CTO论坛推广联盟”制作完成。书中所有内容均来自各联盟成员的论坛(网站)。制作本书的目的是为了集中大家的优势资源,将更多更精彩的内容带给广大技术爱好者。本书是联盟成立以来制作的第一本书。
关键字阅读
频道精选
主编信箱 热线:010-66476606 告诉我们您想看的:专题 文章
关于我们 | 诚聘英才 | 联系我们 | 网站大事 | 意见反馈 | 网站地图
Copyright©2005-2007 51CTO.COM 版权所有