论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Asp.net教程
Tag:静态页面,treeview,gridview,repeater,dataset,sqldatareader,ado.net,上传,三层,ajax,xml,留言本,新闻发布,商城,注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,触发器,socket,form认证,登录,视频教程

.NET中的常见问题

文章类别:Asp.net | 发表日期:2009-8-12 11:25:37

本文主要总结了.NET中常遇到的问题,及其解决的办法.....

常见问题:

1. 数据库连接超时

2. 创建的对象只管用,不管释放

3. 调试(Debug)模式下编译后,就用于应用环境中了

4. 实际作业模式分享

上面的问题就像毒瘤,积累到一定程度就爆发,且影响深远。

1.数据库连接超时篇

若要知道数据库连接超时问题,先看下面一段代码:

[sample-01]

Public Shared Function getOEMPN(ByVal psPN As String, ByRef OEMPN As String) As BSResult
Dim clsResult As New BSResult
Try
clsResult.ResultID = -1
Dim dtResult As New DataTable
Dim Sql As String = String.Empty
Dim clsOraDb As New clsOraClienDb
Dim strConn As String = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
clsOraDb.Open(strConn)  ‘这里Open后,后面看不到 clsOraDb.Close
Sql = "SELECT  SATBMMBRND.OEMPN FRUNO FROM SATBMMBRND  WHERE SATBMMBRND.MATNO = :MATNO"
Dim params() As racleParameter = {New OracleParameter("MATNO", psPN)}
If clsOraDb.FillDataTable(Sql, dtResult, params) = False Then
Return clsResult
End If
If dtResult Is Nothing Then
Return clsResult
End If
If dtResult.Rows.Count > 0 Then
OEMPN = dtResult.Rows(0)("FRUNO").ToString()
Else
OEMPN = ""
End If
clsResult.ResultID = 1
Return clsResult
Catch ex As Exception
clsResult.ResultID = -1
Return clsResult
End Try
End Function

对上述代码行的部分解释:

Dim clsOraDb As New clsOraClienDb:引用数据库连接的类;

clsOraDb.Open(strConn):打开数据库连接;

然后,整个函数你再找不到关闭数据库连接的动作,是要等着操作系统来释放吗? 有人就说啦,看起来好像没有什么大不了的,这仅仅是一个函数而已;数据库打开连接,未关闭不会影响到整个应用程式;果真是这样吗?

让我们谈谈数据库连接的问题,在Oracle数据库里,一般默认的数据库连接数最多也就100多来个,不会超过200个,即使你改变这个连接数;但无论怎样,它的连接数是有限的;不可能无限地供你消耗。

在Web这个程式里,它不仅不会自动关闭数据库连接,象这样的函数还会每次调用,都会重新用掉一个数据库连接;如果象这样的函数很多的话,你就等着一个错误警告页面弹出来,如Database Connection Timeout…等讯息。

这还不算什么,更有甚者,尽然在循环语句里写下面的代码如 :

[sample-02]

Foreach(DataRow row in tabl.select(“”,”ProductID”)……………clsOraDb.Open(strConn)………….Next有人还喜欢玩下面的语句:[sample-03]Foreach(DataRow row in tabl.select(“”,”ProductID”)Foreach(DataColumn col in tbl.columns)……………clsOraDb.Open(strConn)Next ………….Next

说到这,有人就问啦;我在开发环境下测试一点问题都没有呀?是呀,你是没有问题;我想问的是,你开发环境的测试数据有几笔?

现在,问题已经知道在哪里,怎么解决?

针对[sample-01]做如下处理,注意下面代码:

Public Shared Function getOEMPN(ByVal psPN As String, ByRef OEMPN As String) As BSResultDim clsResult As New BSResultTryclsResult.ResultID =
        -1Dim dtResult As New DataTableDim Sql As String = String.EmptyDim clsOraDb As New clsOraClienDbDim strConn As String =
        ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionStringclsOraDb.Open(strConn)  注释:这里Open后,后面看不到 clsOraDb.CloseSql =
        "SELECT  SATBMMBRND.OEMPN FRUNO FROM SATBMMBRND  WHERE SATBMMBRND.MATNO = :MATNO"Dim params() As racleParameter = {New OracleParameter("MATNO", psPN)}If clsOraDb.FillDataTable(Sql, dtResult, params) = False ThenReturn clsResultEnd IfIf dtResult Is Nothing ThenReturn clsResultEnd IfIf dtResult.Rows.Count >
        0 ThenOEMPN = dtResult.Rows(0)("FRUNO").ToString()ElseOEMPN =
        ""End IfclsResult.ResultID =
        1clsOraDb.Close  注释:后面看到 clsOraDb.CloseReturn clsResultCatch ex As ExceptionclsOraDb.Close 注释:程序异常也看到 clsOraDb.CloseclsResult.ResultID =
        -1Return clsResultThrow exEnd TryEnd Function


注意上面的两句代码:clsOraDb.Close和clsOraDb.Close;

在异常处理的时候,特别提醒两点:

(1)你的数据库关闭的时候应该是在代码行0028前,而不是后;

(2)有人不习惯(或者一时疏忽)加上0088行的代码;

针对[Sample-02]和[sample-03],把打开数据库连接写在所有的循环语句之前,如:

以下为引用的内容:

clsOraDb.Open(strConn)Foreach(DataRow row in tabl.select(“”,”ProductID”)……………………….Next 


当然还有另外一个做法,就是用Using语句,提交.NET应用的垃圾收集器自动收集;相关的文章很多;这里不再特别赘述。

2.对象只管创建应用,不管释放篇

我们继续用[Sample-01]的代码:

Dim dtResult As New DataTable

谁会发现它被释放,你不能,我也不能,从来没有被释放过。

“Dim dtResult As New DataTable”行的代码解释是,要在内存划分一个空间给这个定义的对象dtresult;系统要划分多大的空间呢?呀,我没有研究过(留给那些有心人吧,呵呵。.);但有一点,要在内存划分一个空间,就是要占用内存;那么内存有多大呢,不是无限大吧;也是有限的;所有运行上述代码的最终结果是,系统的执行效率越来越慢;有人就怀疑,我有内存1到2G的,加上虚拟内存就更大;我只能说你的怀疑没错;可是你的应用程序就用这么一只函数吗?我想肯定不是;所以上百只函数的应用执行对内存的消耗可想而知;如果是后台自动运行的程序,及时是一个function,也会让系统崩溃;这只是一个简单的例子,有更复杂的;象这样的对象应用还有:Dataset, Datatable,DataReader,DataAdapter,Datagrid.。等;

那么怎么解决这些问题呢?

(1)在Try catch 语句前定义好所用的对象; 如:

Dim dtResult As New DataTable
Dim DR as New DataReader
Dim DS as New Dataset
Try
..
Catch ex As Exception

(2)释放的语句如下:

Dim dtResult As New DataTable
Dim DR as New DataReader
Dim DS as New Dataset
Try
..
……………..
Catch ex As Exception
--释放应用的对象
Throw ex
Finally
--使用完后,释放应用的对象
dtResult.dispose  --从内存里清楚该

 有人习惯写成下面这样:

Dim dtResult As New DataTable
Dim DR as New DataReader
Dim DS as New Dataset
Try
..
‘使用完后,释放应用的对象
dtResult.dispose  ‘从内存里清楚该对象
DR.dispose    ‘从内存里清楚该对象
DS.dispose    ‘从内存里清楚该对象
Catch ex As Exception

这不是也释放了吗?我想问的是,如果程序出现异常,它们会释放吗?我肯定得告诉大家,它们一定不能释放。为了确保程序的稳定运行,我建议大家都来用Try Catch语句。

(3)绝不建议在循环语句写如下的语句:

以下为引用的内容:

Foreach (DataRow row in tabl.select(“”,”ProductID”)
……………
Dim DS new Dataset 记住此乃写代码之大忌;
Dim DT new Databable….
………….
Next

还有一种写法
Dim DS new Dataset
Dim DT new Databable…
Foreach (DataRow row in tabl.select(“”,”ProductID”)

 正确的写法是:

Dim DS new Dataset
Dim DT new Databable…
Try
Foreach (DataRow row in tabl.select(“”,”ProductID”)
DS=nothing  ‘每次使用,都先把内存空间释放出来
DT=nothing  ‘每次使用,都先把内存空间释放出来
DS=GetDatase
DT=GetDatatable……………
.
………….
Next
Catch ex As Exception
Throw ex
Finally
DS.dispose
DT.dispose
End Try

另外,提醒大家一点,记得用 For Each 语句替代For i=0 to Rowcount-1;这样的效率改善也是明显的;

 

上一篇:{教程}.NET编程技巧 人气:2468
下一篇:{教程}.NET中的Response对象 人气:3011
视频教程列表
文章教程搜索
 
Asp.net推荐教程
Asp.net热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058