应如何管理函数范围内声明的计时器的清理?

2024-03-24

在下面的代码中,一个Timer在函数内部声明,它也订阅了Elapsed event:

    void StartTimer()
    {
        System.Timers.Timer timer = new System.Timers.Timer(1000);
        timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        timer.AutoReset = false;
        timer.Start();
    }

函数完成后,将引用Timer丢失了(我猜)。

是否Elapsed当对象被销毁时,事件会自动取消注册,或者如果没有,事件可以在 Elapsed 事件本身中取消注册:

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        var timer = (System.Timers.Timer)sender;
        timer.Elapsed -= timer_Elapsed;
    }

这种方法是否仍然允许正确清理对象,或者出于这个原因永远不应在函数的本地范围内声明计时器?


这里的规则很复杂,你看不到CLR内部发生了什么。它维护一个活动计时器列表,System.Timers.Timer 在该列表中有一个引用,使其保持活动状态并防止其被垃圾收集。在您的情况下是必要的,因为 StartTimer() 方法中的局部变量不足以使其保持活动状态。

当 AutoReset = false 时,CLR 在计时器滴答时将其从列表中删除。这only左边的参考是senderElapsed 事件处理程序中的参数。

如果您没有使用显式重新启用计时器sender,从而将其放回到 CLR 队列中,那么 Timer 对象就不再有引用了。每当 GC 运行时,它就会被垃圾收集。

取消订阅 Elapsed 事件处理程序对此没有影响。这是另一个很难看到的细节,您的事件订阅添加了对this。换句话说,Timer 对象实际上使外部对象保持活动状态。这当然是一件好事,您不希望您的对象被垃圾收集,而计时器仍然可以调用您的 Elapsed 事件处理程序。如果你want如果计时器没有延长对象的生命周期,那么您将不得不做更多的工作。现在有必要明确地取消订阅事件处理程序and停止计时器。这确实需要您保留对 Timer 对象的引用。

另请记住,如果您的类本身实现了 IDisposable,那么它也应该处理 Timer。这是必要的,因为您通常不希望 Elapsed 事件处理程序在已处置的对象上运行,这往往会触发 ObjectDisposeExceptions。这也是将 Timer 对象引用存储在类的字段中的原因。请注意隐藏在地垫下的非常讨厌的线程竞赛错误,Elapsed 事件仍然可以运行after or while您调用计时器的 Dispose() 方法。需要进行联锁,以防止程序每年或每月一次因蓝月亮而崩溃。与允许代码在工作线程上运行并访问共享状态时必须采取的正常预防措施没有什么不同。

总而言之,如果您不再使用 Timer,那么将其处理在 Elapsed 事件处理程序中是合乎逻辑的做法。实际上没有必要,不活动的计时器不会消耗系统资源,但 .NET 程序员通常不愿意跳过它。同样,线程竞争是可能的,您可能会处置已经处置的计时器,但这不会造成麻烦。

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

应如何管理函数范围内声明的计时器的清理? 的相关文章

随机推荐

  • Nodemon 错误:“已达到文件观察器数量的系统限制”

    我在学GraphQL https en wikipedia org wiki GraphQL我正在使用prisma binding用于 GraphQL 操作 我正面临着这个nodemon当我启动 Node js 服务器时出现错误 它给了我由
  • 如何“chartr”“-”(或转义范围)?

    在 R 中可以使用chartr将字符从一种更改为另一种 例如 chartr aor u Stackoverflow 1 Stuck ve fl w 模式可以是范围 例如chartr a hwo 0 9 Stackoverflow 但长度需要
  • 鸢尾花数据集未显示“物种”列

    我正在 Python 上使用 numpy 和 pandas 来学习如何处理数据帧 我正在 Collaboratory 上编码 并且已加载 Iris 数据集 但由于某种原因 我的数据框中没有 物种 列 也许我以错误的方式加载了它 我很乐意就此
  • 数据库MN关系

    我正在上数据库管理系统课程 绝对初学者 并且正在为一个非常简单的博客系统开发数据库 我有一个关于博客文章和帖子所属类别之间的 M N 关系的问题 一篇博客文章可以属于多个类别 该方案的部分如下所示 Scheme http creo prev
  • CocoaPods 和 GitHub 分叉

    这是我第一次 fork GitHub 项目 我对 CocoaPods 也不太熟悉 所以请耐心等待 基本上 我在 GitHub 上分叉了一个项目 在我的项目中使用了以下内容Podfile pod REActivityViewControlle
  • 找到所需类 javax.faces.FactoryFinder 的多个版本

    我开始使用 JSF2 0 我按照教程进行操作 没有任何问题 一切正常 我使用 Eclipse Helios 但我注意到一些我无法理解的事情 该教程说要为 JSF 2 添加 Project Facet 我没有做这样的事情 一切正常 因此 为了
  • 将元素上具有多个 Css 类的 HTML 文件导入 Excel 时出现问题

    如果为 HTML 元素指定了多个 CSS 类 Excel 看起来不会理解 HTML 属性 class 例如 如果 class A B 指向标签 TD Excel 将为该标签使用空样式 我有这些 html 代码
  • 如何在Python中读取键盘输入

    我在 Python 中遇到键盘输入问题 我尝试了 raw input 并且它只被调用一次 但我想在用户每次按任意键时读取键盘输入 我该怎么做 感谢您的回答 例如 你有这样的 Python 代码 file1 py bin python do
  • Likert 数据的 R 频率表

    我认为这是一项基本任务 但事实证明并非如此 我有一系列调查 需要将其转换为每个调查的频率表 例如 调查 1 包含 6 个问题 参与者有 5 个回答选项 对于每项调查 我需要生成一个表格 其中包含每个问题 在本示例中有 6 个 以及对每个问题
  • 在 JavaScript 中取消转义 HTML 实体?

    我有一些与 XML RPC 后端通信的 JavaScript 代码 XML RPC 返回以下形式的字符串 img src myimage jpg 但是 当我使用 JavaScript 将字符串插入 HTML 时 它们会按字面意思呈现 我没有
  • PHP 中的电子邮件跟踪技术

    我正在用 php 做一个新闻通讯管理 我需要跟踪打开我们新闻通讯的访问者 我已在新闻通讯中插入了跟踪图像 但这似乎不起作用 使用 Shift 邮件程序 可以选择将内嵌图像嵌入到时事通讯中 是否可以使用此内联图像进行跟踪 还有其他技术可以跟踪
  • @WebServlet 注释无法识别;初始化不运行

    我正在尝试学习注释 我目前有一个 Web 应用程序 当该应用程序在 Tomcat 中启动时 该应用程序会运行 init 以下代码有效 web xml
  • 为什么“分段错误”在 C 中仍然存在

    操作系统中的分段是一个与时间本身一样古老的概念 至少根据我的教授的说法 大多数现代操作系统已经放弃了分段的概念 现在主要依靠分页来实现内存保护 从而防止每个进程访问除自己的内存之外的任何其他内存 那么我们如何在 C 中仍然遇到 分段错误 在
  • Xcode Storyboard 在 UI 元素周围显示蓝色框架。我该如何关闭此功能?

    老实说 我不确定我在这里做了什么 我以前从未见过这个 Xcode 现在在我的 Storyboard 中的每个 UI 元素周围显示蓝色框架 这适用于其中的所有视图控制器 我该如何撤消或修复此问题 请看下面的截图 它们是 UI 元素的边界矩形
  • 当我使用 Finchley.M5 时,spring-cloud-starter-eureka 无法解析

    尝试使用 Spring Cloud Gateway 创建我自己的 api 网关 下面是我的 build gradle 文件 buildscript ext springBootVersion 1 5 9 RELEASE apply plug
  • MSVC 内联 ASM 到 GCC

    我正在尝试处理 MSVC 和 GCC 编译器 同时更新此代码库以在 GCC 上工作 但我不确定 GCC 内联 ASM 到底是如何工作的 现在我不太擅长将 ASM 翻译成 C 否则我只会使用 C 而不是 ASM SLONG Div16 sig
  • 用于填充电子表格列的一维数组

    我正在使用内置的组服务来提取用户名列表 function getUsersInGroup group var usersInGroup GroupsApp getGroupByEmail group getUsers return user
  • throw 和 $pscmdlet.ThrowTerminateerror() 之间的区别?

    在 PowerShell 中 有什么区别throw ErrorMsg and PScmdlet ThrowTerminatingError ErrorMsg 它们是相同还是不同 如果它们不同 哪一个更可取 Throw创建一个script 终
  • R install_github:错误:无法安装“未知包”[重复]

    这个问题在这里已经有答案了 我是 GitHub 的新手 我很困惑 我无法得到install github上班 我按照此处的有用说明设置了我的帐户 https kbroman org github tutorial pages init ht
  • 应如何管理函数范围内声明的计时器的清理?

    在下面的代码中 一个Timer在函数内部声明 它也订阅了Elapsed event void StartTimer System Timers Timer timer new System Timers Timer 1000 timer E