日期:2014-05-18  浏览次数:21003 次

WinForm高手进,设计器的代码有点疑惑。
如下系统生成的设计代码,有什么作用?
  我注释了1,2,3处代码,只有注释3导致不能关闭窗体。1,2的注释没有影响,窗体可以正常运行。
  高手帮忙详细解释哈,或者给个说明此问题的链接文章,谢谢。
namespace WindowsApplication1
{
  partial class TestDes
  {
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  1 // private System.ComponentModel.IContainer components = null;  

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
  protected override void Dispose(bool disposing)
  {
  2 // if (disposing && (components != null))
  // {
  // components.Dispose();

  // }

  3 // base.Dispose(disposing);
  }

  #region Windows 窗体设计器生成的代码

------解决方案--------------------
http://www.cnblogs.com/Allnen/archive/2008/05/23/1206081.html
------解决方案--------------------
其实你的疑问就是Dispose这个方法

这是个什么方法呢?
他是IDisposable接口中的方法.执行与释放或重置非托管资源相关的应用程序定义的任务

那么他有什么用呢?

实现此方法时,可通过在包容层次结构中传播调用来确保释放所有保持的资源。例如,如果对象 A 分配对象 B,而对象 B 又分配对象 C,那么 A 的 Dispose 实现必须对 B 调用 Dispose,而 B 反过来必须对 C 调用 Dispose。如果一个对象的基类实现 IDisposable,该对象还必须调用其基类的 Dispose 方法。

如果某对象的 Dispose 方法被调用一次以上,则该对象必须忽略第一次调用后的所有调用。如果对象的 Dispose 方法被多次调用,该对象一定不要引发异常。除 Dispose 之外的实例方法在资源已释放时会引发 ObjectDisposedException。

用户可能期望资源类型使用特定的约定来表示已分配状态和已释放状态。流类即是这样一种示例,传统上认为它们要么打开要么关闭。具有此种约定的类的实施者可能选择实现具有自定义名称(如“Close”)的公用方法来调用 Dispose 方法。

因为 Dispose 方法必须显式进行调用,所以,实现 IDisposable 的对象还必须实现一个终结器,以便在未调用 Dispose 时处理释放资源问题。默认情况下,垃圾回收器会在回收一个对象的内存之前自动调用该对象的终结器。然而,在调用 Dispose 方法后,通常不需要垃圾回收器调用已释放对象的终结器。为防止自动终止,Dispose 实现可以调用 GC.SuppressFinalize 方法

------解决方案--------------------
new操作会分配内存,而这是在.NET语意中定义的,其实它不只分配内存,还会做很多初始化的工作,它会把对象的地址记录起来,并维护一个引用计数。这种对象占用的内存都是托管资源。而对于某些对象,如窗体,除了分配这些成员变量的内存空间外,最终会调用到CreateWindowEx这个API函数,调用到它之后系统会创建一块数据区来存储这个窗体的相关信息,并返回一个句柄(地址经过复杂运算之后的值)来标识这个窗体,因为是API函数分配的内存,自然不在托管平台的管理之下,要释放这个窗体所占的内存要调用DestoryWindow这个API,那么很显然这个窗体的相关信息所占的内存就是非托管资源。因此Form对象既占用的托管资源(成员变量),也占用了非托管资源(窗体句柄)。

所有涉及句柄的对象都类似。

同时,在.NET中也提供了非托管内存的创建,用于与平台交互,如结构体的数据传递等。

从我看来,托管无非是在编译器上做了手脚,将简单的语句编译成复杂的语句,增加了引用计数等操作,同时改写了堆的内存管理器而已。因此可以这么说,使用托管平台下的内存管理器分配的内促就是托管资源,而API函数是基于系统的,它如果有分配内存,那它必然是非托管资源。

再说明一下:你可以这么认为,句柄就是系统内存的一个指针,它指向一个结构体,该结构体是描述某一个内核对象的相关信息,如进程、线程、窗体等。