VB.NET之旅(二)—构造与析构

VB.NET之旅(二)—构造与析构,第1张

概述 大李在Form1窗体的实例被隐藏的时候,关闭了Form2窗体的实例,使我失去了对主线程的人工控制,进程无法正常关闭了。只好使用Ctrl+Alt+Del调出系统进程管理器,强行中止了该进程。为了避免抬头看见大李的笑脸,我只好低头想办法。   有了,我只要能截获Form2实例关闭的消息,不就可以再调出隐藏的主线程窗体了吗?在Form2的基类事件(Base Class Event)中重载Closing 大李在Form1窗体的实例被隐藏的时候,关闭了Form2窗体的实例,使我失去了对主线程的人工控制,进程无法正常关闭了。只好使用Ctrl+Alt+Del调出系统进程管理器,强行中止了该进程。为了避免抬头看见大李的笑脸,我只好低头想办法。

  有了,我只要能截获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之旅(二)—构造与析构所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1290282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存