IDisposable 实现 - “if(处置)”中应该包含什么内容

2023-12-27

我一直在修复 winforms 应用程序中的一些内存泄漏问题,并注意到一些未明确处理的一次性对象(开发人员尚未调用 Dispose 方法)。 Finalize 方法的实现也没有帮助,因为它没有进入if (disposing)条款。所有的静态事件注销和集合清除都已放入if (disposing)条款。如果对象是一次性的,最佳实践是调用 Dispose,但不幸的是有时会发生这种情况

如果存在非托管对象、静态事件处理程序和一些需要在处置时清除的托管集合。如何决定什么应该进去,什么应该出去if (disposing) clause.

处置方法。 http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
    if (!disposed)
    {
        if (disposing)
        {
            // Free other state (managed objects).
        }

         // Free your own state (unmanaged objects).
         // Set large fields to null.
         disposed = true;
     }
 }

It says http://msdn.microsoft.com/en-us/library/system.idisposable.aspx管理对象应该在if (disposing)只有当开发者显式调用Dispose方法时才能正常执行。如果 Finalize 方法已经实现并且开发人员忘记调用 Dispose 方法,则通过 Finalizer 到达这里的执行不会进入if (disposing)部分。

以下是我的问题。

  1. 如果我有导致内存泄漏的静态事件处理程序,我应该在哪里取消注册它们?进或出if (disposing)条款?

  2. 如果我有一些导致内存泄漏的集合,我应该在哪里清除它们?进或出if (disposing)条款?

  3. 如果我使用第三方一次性对象(例如:devExpress winform 控件),我不确定它们是托管对象还是非托管对象。假设我想在处理表单时处理它们。我如何知道什么是托管对象,什么是非托管对象?一次性不是这么说的吗?在这种情况下,如何决定什么应该进去,什么应该出去if (disposing)条款?

  4. 如果我不确定某些托管或非托管的事件可能会因处置/清除/取消注册事件而产生不良后果if (disposing)条款?假设它在处理之前检查是否为空?

Edit

我的意思是事件取消注册如下所示。发布者是一个长期存在的实例,下面一行位于订阅者的构造函数中。在这种情况下,订阅者需要取消注册事件并在发布者之前进行处理。

publisher.DoSomeEvent += subscriber.DoSomething;

广义上讲,托管资源被部署在内部if (disposing)以及其外部的非托管资源。处置模式的工作原理如下:

  1. if (disposed) {

    如果该对象已被处置,请不要再次处置它。

  2. if (disposing) {

    如果以编程方式请求处置(true),处置该对象拥有的托管资源(IDisposable 对象)。

    如果处置是由垃圾收集器造成的(false),不要处置托管资源,因为垃圾收集器可能已经处置了拥有的托管资源,并且肯定会在应用程序终止之前处置它们。

  3. }

    处置非托管资源并释放对它们的所有引用。第 1 步确保这只发生一次。

  4. disposed = true

    将此对象标记为已处置,以防止重复处置。重复处置可能会在步骤 2 或 3 中导致 NullReferenceException。

问题1
不要将它们丢弃在Dispose根本没有方法。如果您处置该类的多个实例会发生什么?您每次都会处理静态成员,尽管它们已经被处理过。我找到的解决方案是处理AppDomain.DomainUnloaded http://msdn.microsoft.com/en-us/library/system.appdomain.domainunload.aspx事件并在那里执行静态处理。

问题2
这完全取决于集合中的项目是托管的还是非托管的。可能值得创建托管包装器来为您正在使用的任何非托管类实现 IDisposable,以确保所有对象都受到管理。

问题3
IDisposable 是一个托管接口。如果一个类实现了 IDisposable,那么它就是一个托管类。处理里面的托管对象if (disposing)。如果它没有实现 IDisposable,则它要么是托管的并且不需要处置,要么是非托管的并且应该在外部处置if (disposing).

问题4
如果应用程序意外终止,或者不使用手动处置,垃圾收集器将以随机顺序处置所有对象。子对象可能会在其父对象被处置之前被处置,从而导致子对象被父对象第二次处置。大多数托管对象都可以安全地多次处置,但前提是它们已正确构建。如果多次处置某个对象,您可能会面临(尽管不太可能)导致 gargabe 收集失败的风险。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IDisposable 实现 - “if(处置)”中应该包含什么内容 的相关文章

  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 如何将pdf页面设置设置为打印属性对话框?

    大家好 我想知道如何设置 pdf 页面设置到打印属性对话框 例如 如果我的 PDF 页面设置为横向 则布局会自动显示横向而不是纵向 如果我的 PDF 页面设置为纵向 则布局会自动显示纵向 我在这个主题上做了很多研发 但没有找到任何满意的链接
  • 在 GCC 和 Clang 下,使用 lambda 的简单 RAII 包装器的复制初始化意外失败

    我在创建一个简单的 RAII 包装器时遇到了一个意想不到的问题 更不用说下面代码的逻辑不完整性了 复制构造函数和赋值运算符未删除等 这意味着是一个SSCCE 令我印象深刻的是复制初始化我的包装器与临时 lambda 的结果会导致编译错误 而
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 在通过网络发送之前压缩位图

    我正在尝试通过网络发送位图屏幕截图 因此我需要在发送之前对其进行压缩 有一个库或方法可以做到这一点吗 当您将图像保存到流时 您have选择一种格式 几乎所有位图格式 bmp gif jpg png 都使用一种或多种压缩形式 因此 只需选择适
  • 生成 .tail IL 指令的简单 F# 代码是什么?

    我想看看 tailIL 指令 但我一直在编写的使用尾部调用的简单递归函数显然已优化为循环 我实际上是在猜测这一点 因为我不完全确定反射器中的循环是什么样的 我绝对没有看到任何 tail不过操作码 我在项目的属性中检查了 生成尾部调用 我还尝
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 在“using”语句中使用各种类型 (C#)

    自从C usingstatements只是try finally dispose 的语法糖 为什么它接受多个对象仅当它们属于同一类型时 我不明白 因为它们需要的只是 IDisposable 如果它们都实现 IDisposable 应该没问题
  • QThread - 使用槽 quit() 退出线程

    我想在线程完成运行时通知对象 但是 我无法让线程正确退出 我有以下代码 处理器 cpp thread new QThread tw new ThreadWorker connect tw SIGNAL updateStatus QStrin
  • c# 如何生成锦标赛括号 HTML 表

    所以我已经被这个问题困扰了三个星期 但我一生都无法弄清楚 我想做的是使用表格获得这种输出 演示 http www esl world net masters season6 hanover sc2 playoffs rankings htt
  • C# 中处理 SQL 死锁的模式?

    我正在用 C 编写一个访问 SQL Server 2005 数据库的应用程序 该应用程序是数据库密集型的 即使我尝试优化所有访问 设置适当的索引等 我预计迟早会遇到死锁 我知道为什么会发生数据库死锁 但我怀疑我能否在某个时候发布不发生死锁的
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • 为什么WCF中不允许方法重载?

    假设这是一个ServiceContract ServiceContract public interface MyService OperationContract int Sum int x int y OperationContract
  • 是什么原因导致 Linq 错误:此方法无法转换为存储表达式?

    我有一堆具有相同 select 语句的 Linq to Entity 方法 所以我想我会很聪明 并将其分离到它自己的方法中以减少冗余 但是当我尝试运行代码时 我得到了以下内容错误 该方法不能转化为 商店表达式 这是我创建的方法 public
  • 无法通过 LINQ to Entities 使用某些功能?

    我正在尝试使用 LINQ 查询在项目上实现搜索功能 由于数据有时包含带有重音符号和其他符号的字符 因此我创建了一种方法来删除这些字符以进行搜索 这是我的代码 var addresses from a in db Addresses join
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 将一个 long 转换为两个 int 以进行重构

    我需要将一个参数作为两个 int 参数传递给 Telerik Report 因为它不能接受长参数 将 long 拆分为两个 int 并在不丢失数据的情况下重建它的最简单方法是什么 使用掩蔽和移位是最好的选择 根据文档 long 保证为 64
  • 正在获取“未终止 [] 设置”。 C# 中的错误

    我正在 C 中使用以下正则表达式 Regex find new Regex url
  • 创建带有部分的选项卡式侧边栏 WPF

    我正在尝试创建一个带有部分的选项卡式侧边栏 如 WPF 中的以下内容 我考虑过几种方法 但是有没有更简单 更优雅的方法呢 方法一 列表框 Using a ListBox并将 SelectedItem 绑定到右侧内容控件所绑定的值 为了区分标
  • 如何从函数返回矩阵(二维数组)? (C)

    我创建了一个生成宾果板的函数 我想返回宾果板 正如我没想到的那样 它不起作用 这是函数 int generateBoard int board N M i j fillNum Boolean exists True initilize se

随机推荐

  • 使用 Python 识别 Mac OS X 中的包目录

    Mac OS X Finder 使用 包 的概念使某些文件夹的内容对用户不透明 我在用着os walk 枚举目录树 并且我想跳过对应用程序包等包的枚举 The mdls命令行实用程序可用于检查是否com apple package在里面kM
  • XSL:只有文件名,没有路径

    我是 XSL 编程新手 我想这是一个简单的问题 如何获取没有路径的文件名 目前我的代码如下所示 我得到了整个路径 结果 xml
  • Spring集成测试不回滚

    我正在使用 Spring Hibernate H2 我在集成测试中执行数据库操作 通过调用服务类 我希望 Spring 在每个测试方法之后回滚更改 但我无法让它工作 起初我使用MySQL 带有MyISAM 不支持事务 但是换成H2后问题仍然
  • 使用 $lookup mongodb 填充到深层

    我正在使用 lookup 加入两个集合并从以下查询中获取数据 let condition status ne config PROJECT STATUS completed assignId mongoose Types ObjectId
  • 具有最大高度和最大宽度的响应式图像

    我有这个 html 和 CSS div class kalim img src div CSS kalim display inline block kalim img max width 800px width auto max heig
  • Hibernate 和 Jackson 惰性序列化

    我正在开发一个使用 Hibernate 和 Jackson 来序列化我的对象的项目 我想我明白它应该如何工作 但我无法让它发挥作用 如果我理解得很好 一旦关系获取模式设置为LAZY 如果你想要这个关系 你就必须初始化它 这是我的课程 Ent
  • TensorFlow 中 AdamOptimizer 的学习率不会改变

    我想看看训练期间学习率如何变化 打印出来或创建摘要并在张量板上可视化 这是我迄今为止所掌握的代码片段 optimizer tf train AdamOptimizer 1e 3 grads and vars optimizer comput
  • 通过 Composer 安装或复制供应商文件夹

    我想知道 在部署基于 Composer 的项目时 为什么大多数人建议通过 SSH 连接到服务器并安装 Composer 并下载依赖项 如下所示 curl sS https getcomposer org installer php mv c
  • Angular ng-click 在 Bootstrap 下拉菜单中不起作用

    我有一些基于 Bootstrap 3 下拉菜单的过滤器 但由于某些奇怪的原因 它们在实际的下拉菜单中不起作用 但如果我复制粘贴它并将其放在外面 它就可以正常工作 div div class btn group div div
  • 限制相机旋转角度

    我希望能够在某个点之后限制相机旋转 并且只能在某个区域内旋转 这是到目前为止的代码 void Update float mouseX Input GetAxis Mouse X float mouseY Input GetAxis Mous
  • 有没有办法使用 wrk 将参数传递给 GET 请求?

    我需要对以参数作为输入的 REST API 进行基准测试 我想知道是否有办法使用wrk 现在我没有看到这样的选项 user Ubuntu K56CA wrk wrk Usage wrk
  • 如何设置默认使用的 php.ini,OSX Yosemite

    我使用 OSX Yosemite 设置了一个新环境 我正在使用内置的 PHP 我想更改 php ini 中的一些配置 例如 date timezone 但尽管重新启动了 apache 服务器 sudo apachectl restart 但
  • 逐字字符串文字 v 转义序列

    C 编译器或 NET 运行时处理逐字字符串文本与使用转义序列 即性能 的方式有什么区别 还是只是设计时风格的问题 例如 var pathA c somewhere var pathB c somewhere 我想它们的编译方式是相同的 这并
  • 什么是未定义的引用/未解析的外部符号错误以及如何在 Fortran 中修复它?

    我正在尝试构建 Fortran 程序 但收到有关未定义引用或未解析的外部符号的错误 我见过另一个问题 https stackoverflow com q 12573816关于这些错误 但答案大多是针对 C 的 使用 Fortran 编写时出
  • 由于“只读文件系统”,Google Kubernetes Engine (GKE) 集群“创建挂载源路径时出错”

    我有一个具有以下配置的容器 spec template spec restartPolicy OnFailure volumes name local src hostPath path src analysis src type Dire
  • 如何强制协调员行动以特定频率实现?

    我想知道是否有可能 如何强制协调员定期具体化或实例化工作流程 即使先前实例化的工作流程尚未完成 让我解释 我有一个简单的协调员 如下所示
  • 如何在C#中实现单例?

    如何在 C 中实现单例模式 我想将常量和一些基本函数放入其中 因为我在项目中到处都使用它们 我想让它们 全局 而不需要手动绑定它们我创建的每个对象 如果您只是存储一些全局值并且有一些不需要状态的方法 则不需要单例 只需将类及其属性 方法设为
  • 符号可见性、异常、运行时错误

    我尝试更好地理解符号可见性 海湾合作委员会维基百科 http gcc gnu org wiki Visibility http gcc gnu org wiki Visibility 有一个关于 C 异常问题 的部分 根据 GCC Wiki
  • 创建一个 N 维数组,其中 N 在运行时确定 (C++)

    我正在将 N 维图像立方体编码为不同的图像格式 我直到运行时才知道图像的尺寸 并且我用来读取原始图像的库需要一个 N 维数组目标缓冲区作为参数 如何在 C 中声明这样的数组 谢谢 简而言之 您不能在 C 中声明这样的数组 数组的维数是类型的
  • IDisposable 实现 - “if(处置)”中应该包含什么内容

    我一直在修复 winforms 应用程序中的一些内存泄漏问题 并注意到一些未明确处理的一次性对象 开发人员尚未调用 Dispose 方法 Finalize 方法的实现也没有帮助 因为它没有进入if disposing 条款 所有的静态事件注