快捷搜索:

引以为戒 .NET开发者常犯的错误

.NET开拓历程中不是程式的无法运行,便是程式的效率慢的同蜗牛在爬; 这种环境在.NET的新手中尤其常见;我不知道为什么,一些先容.NET开拓的书籍里引用的例子代码,也对此问题熟视无睹,尤其让我愁闷的是一些我爱好的书也呈现了同样的问题。

这篇文章不仅对.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

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

留意上面的两句代码: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..等;

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”)

DS=GetDatase

DT=GetDatatable……………

.

………….

Next

精确的写法是:

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;这样的效率改良也是显着的;

3.调试(Debug)模式下编译就用于利用情况中篇

大年夜家看下面的图片:

上面三个环节,任何一个发生问题,都邑影响到系统的效率;我分享我们实际的功课的历程发生的一些环境,及怎么办理这些问题。

(1)内存应用达到峰值,导致法度榜样无法继承运行;

有个同事分享了他们的履历如下(原话分享):

我们有一些程式是server跑的Job,并有越来越多之势。而大年夜家在写程式的时刻可能对照少斟酌到耗内存这个问题。

下面的例子大概会给我们一点启示。

下面也是原话:

Pls help to check the Run In Rack Job program .  It will no response after running two or three days . the AP server Memory usage will over 2.5G . after we close the the program , Memory will decrease to 1.5 .

大年夜请安思是:在办事器端(也叫后台)自动跑的一只程式,运行了两三天后,竣事运行了;反省Server的内存应用率时,发明跨越了2.5G;在关掉落了这只程式后,它就降到了1.5G…下面的图片为证:

(2)进程哀求过多,导致CPU无法及时处置惩罚,法度榜样效率反映较慢。

下面都是同事的原话:

“年后产量徐徐增添,新的问题又呈现了。从Server Performance上阐发,和上次Memory过高不合的是CPU应用率过高。每当CPU过高的时刻,产线会大年夜面积的反映说慢(这点和连接到哪台AP有关系)。每次慢的时刻,我们就找到CPU过高的那台AP,recycle IIS的application pool后就OK了。于是我么再次找到Bon协助阐发(结论:微软结案申报 20090226V1 - SRT090119833891 Web service can't serve IISReset can fix.msg)。并给出了开拓法度榜样时的一些建议。

结论大年夜致是说,没有进程占用了分外高的CPU,也没有进程占用CPU光阴过长。只是对DB的哀求的进程过多(对照吻合3厂的实际状况—附件多,刷的快),加起来就整体过高。还发清楚明了很多DLL是built in debug mode,这些DLL占用了过多的memory资本。后来根据Bon的建议,我们改动了IIS application pool的设定如下,办理过多哀求不能及时处置惩罚,而造成CPU过高的问题。”

这里有一些问答关于利用连接池(Application Pool)的设定,对理解这样的设置有必然的赞助:

1. Is one application pool’s maximum memory usage 1.5G?

A&: Each application pool is a w3wp.exe. w3wp.exe is a process. Every process has 2 G User mode virtual address, so the maximum memory usage for application pool is 2G. However, you can’t make sure that there is no memory fragment issue. Therefore, Out of memory always occur after 1.5 G according to our experience.

2. Is each application pool independent on memory usage?

A&: Different application pools are different w3wp.exe, so each application pool’s maximum memory usage is 2G.

3. Can setup maximum CPU usage on each application pool?

A&: You can monitor it, but you can’t setup it.

您可能还会对下面的文章感兴趣: