如果你在程序中使用了任何數(shù)據(jù)庫(kù)對(duì)象(DAO,
創(chuàng)新互聯(lián)專注于黃巖企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計(jì),電子商務(wù)商城網(wǎng)站建設(shè)。黃巖網(wǎng)站建設(shè)公司,為黃巖等地區(qū)提供建站服務(wù)。全流程按需制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
RDO,
或者
ADO),
在退出程序之前,你必須確認(rèn)已經(jīng)關(guān)閉掉了所有已經(jīng)打開(kāi)的記錄、數(shù)據(jù)庫(kù)和數(shù)據(jù)工作臺(tái)(recordsets,
databases,
and
workspaces)。雖然退出程序時(shí)這些對(duì)象的指針都被自動(dòng)施放了,但是如果你自己又不能確認(rèn)是否真正地釋放了打開(kāi)的數(shù)據(jù)庫(kù)對(duì)象,那么就有可能數(shù)據(jù)庫(kù)連接沒(méi)有馬上被釋放掉,從而被這些對(duì)象所占用的內(nèi)存就再也不能被操作系統(tǒng)再次分配。
----
下面有一段放在Form_Unload
事件(或者其他退出模塊中)中的一小段代碼例子,它演示了關(guān)閉所有打開(kāi)的DAO
工作臺(tái)、數(shù)據(jù)庫(kù)和記錄并釋放了被這些對(duì)象占用的內(nèi)存。當(dāng)你退出FORM時(shí),不論在有一個(gè)、100個(gè)甚至沒(méi)有數(shù)據(jù)庫(kù)連接時(shí)都可以使用下面代碼。
Private
Sub
Form_Unload(Cancel
As
Integer)
'
關(guān)閉數(shù)據(jù)庫(kù)對(duì)象并且釋放內(nèi)存
VB中“對(duì)象關(guān)閉時(shí),不允許操作”解決方案
最近兩天在VB里弄一些小程序,好久沒(méi)接觸了,感覺(jué)有些陌生了,還算有點(diǎn)基礎(chǔ)吧,遇到一些小的難題基本上都能解決。不過(guò),這下真的遇到難題了,琢磨半天硬是沒(méi)弄出結(jié)果來(lái),在網(wǎng)上查資料也沒(méi)個(gè)底,如同大海撈針呀,關(guān)鍵是沒(méi)一點(diǎn)正經(jīng)的答案和可行的方案。
問(wèn)題是這樣的,在VB中執(zhí)行存儲(chǔ)過(guò)程,想輸出返回值并將數(shù)據(jù)綁定到DataGrid控件中,本來(lái)是件小菜的問(wèn)題,在.NET、ASP里都做通過(guò),但在VB里卻是折磨了半天也沒(méi)弄出來(lái)。還是自己動(dòng)手吧,有問(wèn)題就得想辦法,一步步來(lái)吧。
先在SQL 2000中寫好存儲(chǔ)過(guò)程了,(這里不再寫出存儲(chǔ)過(guò)程的具體代碼了,也就是一個(gè)返回值,一個(gè)記錄集)然后在VB中引用ADO對(duì)象,輸入如下代碼,以調(diào)用存儲(chǔ)過(guò)程:
Dim lackconn As New ADODB.Connection
lackconn.ConnectionString=Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=boyd;Initial Catalog=mydb;Data Source=(local)
lackconn.CursorLocation = adUseClient '設(shè)置為客戶端
lackconn.Open
Set lackcmd = New ADODB.Command
lackcmd.ActiveConnection = lackconn
lackcmd.CommandText = myproc '這里為存儲(chǔ)過(guò)程名稱
lackcmd.CommandType = adCmdStoredProc '指定為存儲(chǔ)過(guò)程
Set param = lackcmd.CreateParameter(@num, adInteger, adParamReturnValue, 4) '@num為返回值
lackcmd.Parameters.Append param
Set lackrs = New ADODB.Recordset
Set lackrs = lackcmd.Execute()
msgbox 站點(diǎn)總數(shù): lackcmd.Parameters(@num).Value 個(gè)
Set mydatagrid.DataSource = lackrs 'mydatagrid為對(duì)象名稱
mydatagrid.Refresh '刷新DataGrid
'下面關(guān)閉數(shù)據(jù)庫(kù)對(duì)象等略去
就這樣的一個(gè)簡(jiǎn)單的代碼,一運(yùn)行就出錯(cuò),提示錯(cuò)誤在“Set mydatagrid.DataSource = lackrs”,錯(cuò)誤就是“對(duì)象關(guān)閉時(shí),不允許操作”。郁悶ing...,這哪來(lái)的錯(cuò)誤呢?我根本沒(méi)關(guān)閉數(shù)據(jù)庫(kù)連接,其他內(nèi)容也是沒(méi)有問(wèn)題的呀。花了很長(zhǎng)時(shí)間沒(méi)能解決,大清早再打開(kāi)電腦時(shí),靈機(jī)一動(dòng),搞定了。這里將這種現(xiàn)象作下總結(jié),順便記錄一下本次解決過(guò)程。
產(chǎn)生這種現(xiàn)象有幾種原因:
1、數(shù)據(jù)庫(kù)對(duì)象連接被關(guān)閉了,這肯定會(huì)報(bào)錯(cuò)的,當(dāng)然也不能輸出任何結(jié)果的,這時(shí)只需注意“先使用、后關(guān)閉”就行了,解決這樣的問(wèn)題就是暫時(shí)先不要關(guān)閉數(shù)據(jù)庫(kù)連接就行了。
2、返回記錄為空時(shí),也會(huì)報(bào)錯(cuò)。如下面的代碼
sql = select * from dbcn where 狀態(tài)='0'
Set rs = conn.Execute(sql)
If Not rs.EOF Then
For m = 1 To rs.RecordCount
List_status.AddItem rs(1) ( rs(2) ): rs(4)
rs.MoveNext
Next m
End If
如果沒(méi)有數(shù)據(jù)的話,這里也會(huì)提示這樣的錯(cuò)誤,將查詢代碼放到SQL查詢分析器里運(yùn)行一下,果然沒(méi)有數(shù)據(jù),呵呵。當(dāng)然這樣的錯(cuò)誤可以采用一些方法排除或過(guò)濾的。
3、這就是我這次所遇到的問(wèn)題的中心了,我們將目光轉(zhuǎn)向存儲(chǔ)過(guò)程。的確,在SQL查詢分析器里,存儲(chǔ)過(guò)程是正常運(yùn)行,而且不會(huì)報(bào)錯(cuò),也有數(shù)據(jù)。但仔細(xì)想想,因?yàn)樵诖鎯?chǔ)過(guò)程可能包含了有關(guān)SQL語(yǔ)句影響行數(shù)的信息,這樣一來(lái)也就可能會(huì)導(dǎo)致這樣的情況。
打開(kāi)存儲(chǔ)過(guò)程,在begin后面加上一句代碼:set nocount on,屏蔽掉這些信息。OK,VB中的程序巳經(jīng)能夠正常運(yùn)行了,而且數(shù)據(jù)也是正常的。
順便解釋一下吧,打開(kāi)查詢分析器中的幫助,查找一下有關(guān)set nocount on的信息,我們會(huì)找到這些東西:
====================================
SET NOCOUNT
使返回的結(jié)果中不包含有關(guān)受 Transact-SQL 語(yǔ)句影響的行數(shù)的信息。
語(yǔ)法
SET NOCOUNT { ON | OFF }
注釋
當(dāng) SET NOCOUNT 為 ON 時(shí),不返回計(jì)數(shù)(表示受 Transact-SQL 語(yǔ)句影響的行數(shù))。當(dāng) SET NOCOUNT 為 OFF 時(shí),返回計(jì)數(shù)。
即使當(dāng) SET NOCOUNT 為 ON 時(shí),也更新 @@ROWCOUNT 函數(shù)。
當(dāng) SET NOCOUNT 為 ON 時(shí),將不給客戶端發(fā)送存儲(chǔ)過(guò)程中的每個(gè)語(yǔ)句的 DONE_IN_PROC 信息。當(dāng)使用 Microsoft? SQL Server? 提供的實(shí)用工具執(zhí)行查詢時(shí),在 Transact-SQL 語(yǔ)句(如 SELECT、INSERT、UPDATE 和 DELETE)結(jié)束時(shí)將不會(huì)在查詢結(jié)果中顯示nn rows affected。
如果存儲(chǔ)過(guò)程中包含的一些語(yǔ)句并不返回許多實(shí)際的數(shù)據(jù),則該設(shè)置由于大量減少了網(wǎng)絡(luò)流量,因此可顯著提高性能。
SET NOCOUNT 設(shè)置是在執(zhí)行或運(yùn)行時(shí)設(shè)置,而不是在分析時(shí)設(shè)置。
權(quán)限
SET NOCOUNT 權(quán)限默認(rèn)授予所有用戶。
示例
下例在 osql 實(shí)用工具或 SQL Server 查詢分析器中執(zhí)行時(shí),可防止顯示有關(guān)受影響的行數(shù)的信息。
USE pubs
GO
-- Display the count message.
SELECT au_lname
FROM authors
GO
USE pubs
GO
-- SET NOCOUNT to ON and no longer display the count message.
SET NOCOUNT ON
GO
SELECT au_lname
FROM authors
GO
-- Reset SET NOCOUNT to OFF.
SET NOCOUNT OFF
GO
這里點(diǎn)到為止吧,具體的解釋我想MS的幫助會(huì)比我說(shuō)的更專業(yè)更清楚些,參考下吧。
private
sub
command3_click()
pubconn.close
pubconn.open
strconn
你在這里把pubconn關(guān)閉了,而前面
rstable.open
strsql,
pubconn,
adopendynamic,
adlockoptimistic
使用
close
方法關(guān)閉
connection
對(duì)象還將關(guān)閉與連接相關(guān)聯(lián)的任何活動(dòng)
recordset
對(duì)象。
所以rstable也被關(guān)閉了,所以是對(duì)象關(guān)閉時(shí),不允許操作。
.NET目前的垃圾回收機(jī)制不能實(shí)現(xiàn)把對(duì)象真正的立即釋放掉,GC會(huì)對(duì)垃圾進(jìn)行管理,如果垃圾沒(méi)有引用計(jì)數(shù)了,就會(huì)被回收。
編碼的時(shí)候能用托管類盡量用托管類去實(shí)現(xiàn)你的功能,
對(duì)于實(shí)現(xiàn)了IDisposable接口的類,用完了記得調(diào)用close或者Dispose又或者相應(yīng)的方法去釋放資源,最好吧使用using語(yǔ)句塊;
對(duì)于Com對(duì)象,用完了先關(guān)閉,然后調(diào)用Runtime.InteropServices.Marshal.FinalReleaseComObject()方法把Com對(duì)象的引用計(jì)數(shù)設(shè)置為0。當(dāng) COM 對(duì)象的引用計(jì)數(shù)變?yōu)?0 時(shí),通常會(huì)釋放 COM 對(duì)象,不過(guò)這取決于 COM
對(duì)象的實(shí)現(xiàn),而不是運(yùn)行時(shí)可以控制的。最后調(diào)用ComObj = Nothing以釋放ComObj持有的引用。不過(guò)要注意,只有當(dāng)ComObj的生存期相對(duì)于垃圾回收器用于檢測(cè)孤立對(duì)象的時(shí)間來(lái)說(shuō)很長(zhǎng)時(shí),你才應(yīng)該將變量設(shè)置為 Nothing。
有部分來(lái)自MSDN
軟糖來(lái)回答羅:通過(guò)System.Diagnostics命名空間下的Process類來(lái)關(guān)閉程序的進(jìn)程
Dim?進(jìn)程集合?=?Process.GetProcessesByName("進(jìn)程名稱")
For?Each?進(jìn)程?In?進(jìn)程集合
進(jìn)程.Kill()
'進(jìn)程.Close()?'或者使用關(guān)閉
Next
也可以先獲取所有進(jìn)程,再來(lái)判斷這些進(jìn)程的名稱ProcessName
Dim?獲取本地所有進(jìn)程?=?Process.GetProcesses()
For?Each?進(jìn)程?In?獲取本地所有進(jìn)程
If?進(jìn)程.ProcessName?=?"explorer.exe"?Then?進(jìn)程.Kill()
Next