知识大全 完成器(Finalizer)、程序集名、方法信息

Posted

篇首语:岁寒,然后知松柏之后凋也。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 完成器(Finalizer)、程序集名、方法信息相关的知识,希望对你有一定的参考价值。

完成器(Finalizer)、程序集名、方法信息  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

问题: 在我的类中何时需要实现一个完成器?我是否一定要实现完成器 或者只是在我控制着 非托管资源时才需要实现它?我是否一定要在我的完成器中实现 IDisposable 接口?反之又是如何的呢? 答案: 完成器只是在你控制了需要被清除的资源的才需要实现 举个例子 FileStream 控制了一个本地的文件句柄并且实现了一个完成器 这样也就保证了 FileStream 被垃圾回收器回收时能释放这个句柄 不幸的是 完成器给垃圾回收带来了一定意义上的负担 因此应仅在必要时才使用完成器   IDisposable 接口的实现表明你的类控制了需要被释放的资源 并且允许你的类用户决定是否要释放它们 因此 任何一个类实现了完成器就一定实现了 IDisposable 接口(如果垃圾回收器能自动释放资源 那么也应该允许开发者显式地调用某个方法来完成同样的工作) 但这并不是绝对的 并不是所有实现了IDisposable接口的类都要实现一个完成器    设想一下 我的托管类有一个FileStream类型的私有成员 FileStream 控制了一个非托管的资源并且实现了 IDisposable 接口和完成器 当对该实例不再有引用时 FileStream就变成无法访问的与可终结的了 对我的类而言 它没有理由在注册对象队列里等待终结 因为内嵌的FileStream的实例已经被注册了 另一方面 考虑到我的类应该为用户提供方法以立即释放它所控制的资源 无论这种方法是直接地还是间接的 因此我的类应当实现IDisposable接口 我的Dispose()实现很简单 它只是简单地调用了FileStream的Dispose()方法 切记 尽管如此 你也需要特别小心地释放共享资源(比如正被别的实例使用的资源) 如果你编写一个类从外部释放资源而使该资源可用 请确保你的文档在这个主题上是清晰明确的 这样其他人就知道是否正在移交他们给你的那些资源的控制权了    如果你的类不需要实现完成器 在你的Dispose()方法中应当调用GC SuppressFinalize()方法 以确保系统不会去调用你的实例的完成器 这样你的实例同时也会从待终结对象集合中被删除 从而减轻了垃圾回收器在回收过程中的负担 贯穿于Microsoft NET Framework中常见的实现模式是给Dispose()方法添加一个Boolean(逻辑)类型的参数 这个Boolean类型的参数指示这个类是否因IDisposable Dispose()方法被调用或者完成器在运行而正在被释放(完成器与IDisposable Dispose()都是委托到该方法上的) 如果确定它要被释放 GC SuppressFinalize()就要被调用 如果是通过完成器被释放 就要避免再使用你的类中实现完成器的 托管成员 因为它们可能已经被终结了   Figure 提供了一些指导性的说明 帮助你在合适的时候在你的类中实现这些结构 问题: 我希望把一些关系到应用程序性能的操作建立在计算机可用内存的基础上 如何才能最简单地从操作系统获取这些信息? 答案: 尽管我知道获取这类信息其他的一些方法 但当我发现WMI (Windows Management Instrumentation Windows管理规范)时 我发现它才是完成这类工作最佳的方式 Win _OperatingSystem类提供了关于操作系统事件的丰富信息 System Management命名空间则提供了大量的类来访问WMI的数据 你可以使用 Figure 中的ManagementObjectSearcher类来查询Win _OperatingSystem TotalVisibleMemorySize的值 因为 ManagementObjectCollection (由ManagementObjectSearcher返回)没有公开访问集合内部元素的方法 因此我使用了一个foreach循环来枚举出其中的每一个成员 而且因为我只关心其中的一个值 所以我在第一次枚举完成后就停止了循环    注意TotalVisibleMemorySize返回的值可能并不是当前的物理内存总量 而是向操作系统报告可利用的内存量 你可以从Win _OperatingSystem(Win _OperatingSystem)这个WMI类中学会更多有用的东西 问题: 我尝试着在未将程序集装载入我的AppDomain的情况下 获取该程序集的完全限定名 这可能做到吗? 答案: 绝对能!System Reflection AssemblyName类有一个static类型的方法GetAssemblyName() 这可以返回磁盘上一个程序集的名称AssemblyName 这个方法只是简单地打开这个程序集文件 而不会将它装载入AppDomain 下面的这段代码 就能在控制台上输出从命令行传入的路径参数对应程序集的完全限定名

  static void Main(string [] args) if (args Length > ) try AssemblyName a = AssemblyName GetAssemblyName(args[ ]); Console WriteLine(a Fullname); catch(Exception exc) Console WriteLine(exc Message);

注意 同样的技巧也可以用到本地托管的DLL或者EXE上 你可以在这些文件上挨个地试一试 如果没有异常被抛出 并且返回了一个有效的名字 那么这个文件就是托管的 当然 这种方式在所有的本地文件都触发异常的情况下也存在一些性能上的缺陷 当然还有另一种方法 它不依赖于反射 也不需要装载Portable Executable (PE) 而是通过分析DLL或者EXE的PE头中某个标识位是否被置位 由此确定它是否是 托管的 Managed Extensions for C++ requently Asked Questions中有实现这种方法的C++代码 等价的C#代码请参见 Figure 问题: 在我的C#应用程序里有一大堆的foreach循环 当我检查编译器生成的MSIL 文件时(Microsoft intermediate language Microsoft中间语言)时 我发现其中有的循环被嵌入了一个try/finally块 但我的源代码里并没有使用啊?它们为什么会在这里出现? 答案: 问得好!记住foreach循环是用来枚举那些集合型的数据的 它是通过获取一个枚举器后 使用枚举器的MoveNext操作来实现遍历 并在Current数据属性中返回集合中的当前项 这个枚举器本身则是通过调用该集合对象的GetEnumerator()方法获得的 因为枚举器可能实现了IDisposable接口 所以C#的编译器需要在枚举完成后将其释放 为此 编译器会将这个循环放入一个try块 然后试着在finally块中释放这个枚举器 如果利用GetEnumerator ()方法返回的枚举器实现了IDisposable接口 编译器就会生成一个类似下面这样的finally块

  ((IDisposable)enumerator) Dispose();

如果枚举器没有实现IDisposable接口 那么编译器仍然不得不试着释放这个对象 因为不能确定枚举器的派生类型(从这个函数返回的)没有实现IDisposable接口 于是 编译器又会生成类似这样的一个finally块

  IDisposable disposable = enumerator as IDisposable;if (disposable != null) disposable Dispose();

cha138/Article/program/net/201311/12351

相关参考

知识大全 用户控件包装器的设计与实现

  引言  SPS是一个安全可伸缩的企业级门户服务器可以利用它将SharePoint站点信息和应用程序汇集到一个单一的门户位置用户可以通过门户内容和布局进行个性化的定制更快地找到相关信息目前许多企业和

知识大全 操作无法完成,因为它无法及时启动远程访问连接管理器服务

我的win7系统无法连接网络,显示“错误711:操作无法完成,因为它无法及时启动远程访问连接管理器服务遇到此问题,Windows7用户可以参考以下方案进行解决:首先请确认相同网络环境下,其他计算机是否

在windows系统中,要强行关闭一个正在运行的程序,可以使用任务管理器来结束它,打开任务管理器需按下__

在windows系统中,要强行关闭一个正在运行的程序,可以使用任务管理器来结束它,打开任务管理器需按下_____。A、Ctrl+DelB、Ctrl+Alt+ShiftC、Ctrl+ShiftD、Ctr

已经履行法定生效程序的最后完成稿是

已经履行法定生效程序的最后完成稿是_____。A、正本B、草稿C、定稿D、试行本答案:C解析:定稿是已经履行法定生效程序的最后完成稿,即经机关领导人审核并签发、正式会议讨论通过或经上级机关审核批准的文

集散型控制系统是如何提高系统的功能和效率?

  集散型控制系统的功能和效率的提高是因为由微型机构成的控制装置,其控制功能通过程序来完成。过程控制中常用的功能块,如三态PID调节器、积分器、微分器、运算器、计时器、均衡器、峰值检测器、顺序工作器、

集散型控制系统是如何提高系统的功能和效率?

  集散型控制系统的功能和效率的提高是因为由微型机构成的控制装置,其控制功能通过程序来完成。过程控制中常用的功能块,如三态PID调节器、积分器、微分器、运算器、计时器、均衡器、峰值检测器、顺序工作器、

知识大全 即刻完成你的ASP.NET程序

即刻完成你的ASP.NET程序  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ASPNET的出现

知识大全 Java多线程调试如何完成信息输出处理

Java多线程调试如何完成信息输出处理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多

知识大全 用JSP编写通用信息发布程序

用JSP编写通用信息发布程序  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  信息发布界面  提供

知识大全 ASP程序中错误信息说明

ASP程序中错误信息说明  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Microsoft&nb