当前位置: 首页 > news >正文

肥西县建设局资询网站平面设计正规培训机构

肥西县建设局资询网站,平面设计正规培训机构,营销策划是干嘛的,怎么把网站的标题做的炫酷C# --- dispose机制与using关键字Dispose机制的作用基石:IDisposable 接口如何使用Dispose功能:using 语句如何实现一个标准的 Dispose 模式可能出现的错误与陷阱Dispose机制的作用 .NET 应用程序运行在托管环境(CLR)中&#xff0…

C# --- dispose机制与using关键字

  • Dispose机制的作用
  • 基石:IDisposable 接口
  • 如何使用Dispose功能:using 语句
  • 如何实现一个标准的 Dispose 模式
  • 可能出现的错误与陷阱

Dispose机制的作用

  • .NET 应用程序运行在托管环境(CLR)中,内存由垃圾回收器(Garbage Collector, GC) 自动管理。然而,并非所有资源都是内存。这些资源被称为非托管资源(Unmanaged Resources),例如:
  • 文件句柄(FileStream, StreamReader)
  • 数据库连接(SqlConnection)
  • 网络套接字(Socket, HttpClient)
  • 图形句柄(GDI+ 中的 Pen, Brush)
  • OS 句柄、互斥锁(Mutex)等
  • GC 只知道如何释放内存,但不知道如何释放这些非托管资源。如果这些资源不被正确释放,会导致资源泄漏,最终可能使应用程序或整个系统变得不稳定(例如,耗光所有文件句柄或数据库连接)。
  • Dispose 模式的目的就是提供一个确定性的机制,让开发者能够及时、显式地释放这些宝贵的非托管资源,而不是被动地等待 GC 的最终化。

基石:IDisposable 接口

  • 该机制的核心是 System.IDisposable 接口,它只定义了一个方法:
public interface IDisposable
{void Dispose();
}
  • 任何持有非托管资源的类都应该实现这个接口。Dispose() 方法的作用是:
  • 释放该类持有的非托管资源。
  • 释放该类持有的其他托管资源(这些资源本身也实现了 IDisposable)。
  • 抑制终结(Finalization),如果该类有终结器的话(后面会解释)。

如何使用Dispose功能:using 语句

  • C# 提供了 using 关键字来简化实现了 IDisposable 接口的对象的资源管理。它能确保 Dispose() 方法被调用,即使在 using 块内发生了异常。

语法:

// 方式一:传统 using 块(推荐)
using (var resource = new SomeDisposableResource())
{// 使用 resource// ...
} // 无论是否发生异常,离开此块时 resource.Dispose() 都会被自动调用// 方式二:C# 8.0 引入的 using 声明
using var resource = new SomeDisposableResource();
// 使用 resource
// ...
// 当执行离开当前作用域(方法、代码块)时,resource.Dispose() 会被自动调用

编译器会将 using 语句编译成一个 try…finally 块:

// 你写的代码:
using (var resource = new SomeDisposableResource())
{// 使用 resource
}// 编译器生成的等效代码:
SomeDisposableResource resource = new SomeDisposableResource();
try
{// 使用 resource
}
finally
{if (resource != null)((IDisposable)resource).Dispose();
}

如何实现一个标准的 Dispose 模式

  • 简单地实现一个空的 Dispose() 方法是不够的。.NET 定义了一个标准的模式来正确处理所有场景。这个模式稍微有点复杂,但至关重要。

一个完整的、实现了标准 Dispose 模式的类如下所示:

using System;public class AdvancedResourceHolder : IDisposable
{// 标记资源是否已被释放private bool _disposed = false;// 假设这里持有一个非托管资源(例如一个文件句柄)private IntPtr _unmanagedHandle;// 假设这里持有一个托管资源(它本身也是可释放的)private Stream _managedStream;public AdvancedResourceHolder(string filePath){// 模拟分配非托管资源(例如,调用一个本地API)_unmanagedHandle = /* SomeNativeMethods.AllocateHandle() */;// 分配托管资源_managedStream = new FileStream(filePath, FileMode.Open);}// 公共的 Dispose 方法,供用户显式调用public void Dispose(){// 传入 true,表示是用户主动调用的Dispose(true);// 告诉 GC 不要再调用终结器了,因为资源已经被清理了GC.SuppressFinalize(this);}// 受保护的虚拟 Dispose 方法,是实际进行清理工作的核心方法protected virtual void Dispose(bool disposing){// 如果已经被释放过,则直接返回if (_disposed)return;// 参数 disposing 的含义:// true  -> 用户通过调用 Dispose() 或 using 语句主动释放。// false -> 由终结器线程调用,此时不要再操作其他托管对象。if (disposing){// 释放其他托管资源(它们也有自己的 Dispose 方法)_managedStream?.Dispose();_managedStream = null;}// 释放非托管资源(无论 disposing 是 true 还是 false,都要执行)if (_unmanagedHandle != IntPtr.Zero){// SomeNativeMethods.CloseHandle(_unmanagedHandle);_unmanagedHandle = IntPtr.Zero;}// 标记为已释放_disposed = true;}// 终结器(Finalizer / 析构函数)- 安全网// 只有在没有显式调用 Dispose 的情况下,GC 才会在回收对象时调用它~AdvancedResourceHolder(){// 传入 false,表示是 GC 调用的,不要碰托管资源Dispose(false);}// 一个示例方法,在使用对象前检查是否已被释放public void DoWork(){// 对象已被释放后调用其方法,应抛出 ObjectDisposedExceptionif (_disposed)throw new ObjectDisposedException(GetType().Name);// 正常的业务逻辑...byte[] data = new byte[100];_managedStream.Read(data, 0, data.Length);// 使用 _unmanagedHandle ...}
}

模式关键点解析:

  • Dispose() 方法 (无参数)
  • 公共方法,供使用者调用。
  • 调用 Dispose(true) 执行完整的清理。
  • 调用 GC.SuppressFinalize(this) 告诉 GC:“不用再调用终结器了,我已经清理完了”。这避免了不必要的终结操作,提升性能。
  • Dispose(bool disposing) 方法
  • 这是模式的核心,承载所有清理逻辑。
  • disposing 参数是关键:
  • true:表示是用户主动调用的。此时可以安全地释放托管资源(如 _managedStream.Dispose())和非托管资源。
  • false:表示是终结器调用的。此时只能释放非托管资源。因为终结器运行顺序不确定,你所引用的其他托管对象可能已经被 GC 回收了,再去调用它们的 Dispose() 方法会导致不可预知的行为。
  • 终结器 (Finalizer) (~ClassName)
  • 它是一个安全网,确保即使使用者忘记调用 Dispose(),非托管资源最终也能被释放(尽管不及时)。
  • 重要:拥有终结器的对象在 GC 回收时效率更低,因为它们需要被放入终结队列,等待终结器线程调用。因此,应避免不必要的终结器。
  • 准则:只有直接持有非托管资源的类才需要实现终结器。如果你的类只引用了其他 IDisposable 的托管对象,你不需要终结器,只需在 Dispose(true) 中调用它们的 Dispose() 即可。
  • _disposed 字段
  • 用于防止多次释放资源,这可能会导致异常。
  • 在公共方法中检查此字段,如果对象已释放,则抛出 ObjectDisposedException。

可能出现的错误与陷阱

  • 忘记调用 Dispose():导致资源泄漏。始终使用 using 语句是避免此错误的最佳实践。
  • 在 Dispose() 中抛出异常:这非常危险。Dispose() 通常在 finally 块或 using 语句中被调用。如果在 finally 块中抛出异常,它会掩盖 try 块中抛出的原始异常,使得调试极其困难。Dispose() 方法应被设计为幂等(多次调用效果相同)且不抛出异常(或在极端情况下才抛出)。
  • 在终结器中操作托管对象:如前所述,这会导致未定义行为,因为那些托管对象可能已经被回收了。
  • 没有实现完整的 Dispose 模式:例如,只有 Dispose() 而没有 Dispose(bool) 和终结器,或者清理逻辑不完整。
  • 返回 using 块内的资源:
public Stream GetProblematicStream()
{using (var stream = new FileStream(...)){return stream; // 错误!返回时 stream 会被立即释放!}
}
http://www.dtcms.com/a/459014.html

相关文章:

  • 广告联盟做网站免费制作app平台
  • 硬件开发网站做ppt图片网站 知乎
  • 能量密度的革命:穿透电池从实验室到工厂的迷雾,窥见固态电池的终极未来
  • 官方网站弹幕怎么做永泰建设工程网站
  • 怎样设立网站精神文明建设网站模板
  • 哪一些网站使用vue做的商城网站建设资讯
  • 各大网站网址世界最新新闻
  • 如果制作个人网站房产局官网查询系统
  • 手机网站建设计wordpress模板的网站_网页字体怎么修改?
  • 深圳中国电信网站备案口碑好的vi设计公司
  • asp后台怎么加载网站贴吧引流推广
  • 基于51单片机心率仪—体温心率血氧蓝牙
  • 中小企业建设网站注册安全工程师证书
  • 小学scrach入门项目学习幸运大转盘项目
  • 备案不关闭网站吗游戏创作平台
  • 做企业网站 签合同要注意什么北京高端网站建设飞沐
  • 自己做的动画买给网站网站建设前景展望
  • 做设计去哪些网站下载素材怎样把自己做的网站上传
  • 1.1Java简介
  • 桂市做网站的朋友四川个人网站备案
  • 建设电影网站的关键quot 网站建设话术 quot
  • 小型网站开发语言网站建设表格的属性
  • 大气网站源码下载小程序商城开发北京
  • 学校网站要求广州海珠网站开发方案
  • 服务定制网站活动页面模板
  • 手机站点cn网站建设论文的部首
  • 如何联系网站站长企业网站推广的方法有什么
  • 无锡做网站哪里好连云港做网站制作
  • 蚌埠企业做网站html5网站正在建设中
  • 建行企业银行app官方下载软文怎么优化网站