有了,我只要能截获Form2实例关闭的消息,不就可以再调出隐藏的主线程窗体了吗?在Form2的基类事件(Base Class Event)中重载Closing方法进行处理:
1 2 3 4 | 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试试。”
我背心一凉,隐隐感觉大李等待着的就是这个时候。无奈的我还只能照他说的去做。果然,d出一个出错窗口.
“你关闭了frm2这个Form2的实例,也就结束了这个对象的生存期,”大李看来是蓄势已久了,“这就是出错提示中所说的‘无法访问名为Form2的已处置对象’。当我们关闭一个窗口的时候,会发出一个终止响应,并将该窗口对象,就象上面定义的frm2,送入终止队列,公共语言运行库的垃圾回收器跟踪着这个对象的生存期,此时就会调用此对象基类,比如Form2的dispose方法,用于销毁对象并收回资源。所以……”
“所以我只要判断一下frm2是否被销毁就行了,如果销毁了,我就再构造一个实例不就行了?”我恍然大悟道。
大李第一次微笑地点了点头说:“用frm2.Isdisposed就可以来判断了。”
我心领神会地写道:
1 2 3 4 5 6 7 8 | 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 窗体设计器生成的代码 ":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 方法会大大减损性能,所以我们不会一开始就用它去进行清除工作。”大李稍微解释了一下。
我终于想起了一个重要的问题:“如果总是在模块中定义的全局变量来处理,由于访问范围太大,会不会有安全性的问题?”
“当然,我们可以试试其他的解决方案。”大李总是有备而言。
总结以上是内存溢出为你收集整理的VB.NET之旅(二)—构造与析构全部内容,希望文章能够帮你解决VB.NET之旅(二)—构造与析构所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)