c# - GC.KeepAlive() 和 System.Timers.Timer

标签 c# garbage-collection

我已声明System.Timers.Timer类级别的对象并在构造函数中创建。在另一个方法中启动了计时器。

在已用事件处理程序中,将启用属性设置为 false 并执行一些代码,然后再次将启用属性设置为 true。

我正在获取每个间隔的已发生事件。 问题是在一段时间过去后停止的。

我怀疑 GC 在已用事件处理程序 eventhadler 中将启用属性设置为 false 时收集计时器对象。

所以我希望我的计时器对象设置为保持事件状态。

我应该在哪里申报GC.KeepAlive(timer)在我的项目中?

最佳答案

如果计时器是在类级别声明的,则 GC 不会自动收集它,因为它不会超出范围。将 Enabled 设置为 false 不会导致您描述的行为。你的问题出在别的地方。

我怀疑您的事件处理程序中存在异常。 System.Timers.Timer 吞掉事件处理程序中发生的异常,这意味着如果异常逃逸了事件处理程序,您将永远不会知道它。

我怀疑你的代码是这样写的:

myTimer.Enabled = false;
// do stuff here
myTimer.Enabled = true;

如果在“在这里执行操作”期间引发异常,则该异常会逃脱处理程序,计时器永远不会重新启用,并且计时器代码会吞掉该异常,因此您永远不知道发生了什么事。

您应该像这样编写事件处理程序:

myTimer.Enabled = false;
try
{
    // do stuff here
}
catch (Exception ex)
{
    // handle exceptions
}
finally
{
    myTimer.Enabled = true;
}

您通常只想捕获特定的异常——您知道如何处理的异常。像上面这样捕获所有异常通常是不好的做法。

关于c# - GC.KeepAlive() 和 System.Timers.Timer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14937643/

相关文章:

c# - 使用 SSH.NET 库从 SFTP 下载文件

c# - 使用 C# 的年份中的日期差异

c# - Streams 的奇怪问题

c# - 重试失败的 System.Data.SqlClient 操作的干净方法

Java 垃圾收集 - 如何在调用时查找正在运行的方法

python - 垃圾收集如何处理多个正在运行的进程/线程?

c# - 使用 System.IO.Compression 压缩完整文件夹

java - 在Java中,你能链接两个类之间的垃圾收集吗?

java - 日志管理器和垃圾收集器

python - 扭曲的Python垃圾收集