程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB.NET >> VB.NET之旅(二)—構造與析構

VB.NET之旅(二)—構造與析構

編輯:VB.NET

大李在Form1窗體的實例被隱藏的時候,關閉了Form2窗體的實例,使我失去了 對主線程的人工控制,進程無法正常關閉了。只好使用Ctrl+Alt+Del調出系統進 程管理器,強行中止了該進程。為了避免抬頭看見大李的笑臉,我只好低頭想辦 法。

有了,我只要能截獲Form2實例關閉的消息,不就可以再調出隱藏的 主線程窗體了嗎?在Form2的基類事件(Base Class Event)中重載Closing方法進 行處理:

Private Sub Form2_Closing(ByVal sender As Object,

 ByVal e As _
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        frm1.Show()
    End Sub

哈,很方便,我關閉了Form2窗體的實例後,被隱藏 的那個frm1又出現了。

“嗯,”大李終於發話了,“你 再點擊一下Form1窗體上的Button1試試。”

我背心一涼,隱隱感覺 大李等待著的就是這個時候。無奈的我還只能照他說的去做。果然,彈出一個出 錯窗口.

“你關閉了frm2這個Form2的實例,也就結束了這個對象的生存期 ,”大李看來是蓄勢已久了,“這就是出錯提示中所說的‘無法 訪問名為Form2的已處置對象’。當我們關閉一個窗口的時候,會發出一個 終止響應,並將該窗口對象,就象上面定義的frm2,送入終止隊列,公共語言運 行庫的垃圾回收器跟蹤著這個對象的生存期,此時就會調用此對象基類,比如 Form2的Dispose方法,用於銷毀對象並收回資源。所以 ……”

“所以我只要判斷一下frm2是否被銷毀就 行了,如果銷毀了,我就再構造一個實例不就行了?”我恍然大悟道。

大李第一次微笑地點了點頭說:“用frm2.IsDisposed就可以來判斷 了。”

我心領神會地寫道:

Private Sub 

Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
        If frm2 Is Nothing Or frm2.IsDisposed Then  

‘判斷對象是否被銷毀
            frm2 = New Form2()
        End If
        Me.Hide()
        frm2.Show()
    End Sub

這下完善多了,兩個窗體之間的切換也不會有這麼多 別扭的問題了。我轉過身,看到大李已經找了把椅子坐在我的身邊。

“你來說說,對VB.NET的窗體實例的創建與銷毀的過程吧。 ”

我整理了一下凌亂的思路,長吁了一口氣,開始說:“一個 窗體類,比如Form1類是通過調用其基類,就是Form類的New方法來創建實例、 Dispose方法來銷毀實例。”

“沒錯。”大李邊說話,一 邊在我的程序中點擊開來被代碼窗口自動折疊起來的" Windows 窗體設計器生成 的代碼 ":

Public Sub New()
        MyBase.New()
        '該調用是 Windows 窗體設計器所必需的。
        InitializeComponent()
        '在 InitializeComponent() 調用之後添加任何初始化
    End Sub
    '窗體重寫處置以清理組件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing

 As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

大李開始解說道:“MyBase 關鍵字的行為類似 於引用類的當前實例的基類的對象變量。MyBase 常用於訪問在派生類中被重寫或 隱藏的基類成員。在這段代碼中,MyBase指的當然就是 System.Windows.Forms.Form類了。構造對象時用的New方法是顯式調用的,沒什 麼好解說的。但析構的方法值得一說。”

他看了我一想,繼續說: “Form.Dispose方法是重寫自Control.Dispose方法的,那麼 Control.Dispose方法的含義又是怎麼樣的?它的作用就是:釋放由Control占用 的非托管資源,還可以另外再釋放托管資源。當它參數中的disposing 為 true 則釋放托管資源和非托管資源;為 false 則僅釋放非托管資源。 Form類的 disposing為true。在關閉窗體時自動調用dispose的功能是得益於.net的公共語 言運行庫,運行庫自動處理對象布局和管理對對象的引用,當不再使用對象時釋 放它們。其生存期以這種方式來管理的對象稱為托管數據。自動內存管理消除了 內存洩漏以及其他一些常見的編程錯誤。任何類型的 Dispose 方法都應該釋放它 擁有的所有資源。它還應該通過調用其父類型的 Dispose 方法釋放其基類型擁有 的所有資源。該父類型的 Dispose 方法應該釋放它擁有的所有資源並同樣也調用 其父類型的 Dispose 方法,從而在整個基類型層次結構中傳播該模式。要確保始 終正確地清理資源,Dispose 方法應該可以被多次安全調用而不引發任何異常。 ”

“可是,如果系統問題或應用程序調用上出了問題,不能正 常調用Dispose怎麼辦?”我想起了什麼,問道。

“如果通過 Dispose還釋放不干淨或沒有調用Dispose,系統的垃圾回收器會調用對象的 Finalize 方法進行清除。由於執行 Finalize 方法會大大減損性能,所以我們不 會一開始就用它去進行清除工作。”大李稍微解釋了一下。

我終於 想起了一個重要的問題:“如果總是在模塊中定義的全局變量來處理,由於 訪問范圍太大,會不會有安全性的問題?”

“當然,我們可以 試試其他的解決方案。”大李總是有備而言。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved