2

我收到此代码分析错误:CA1823:AvoidUnusedPrivateFields,对于这行代码:

private static Timer _timer;

在我的类的构造函数中,我有这个:

_timer = new Timer(OnTimerElapsed, _autoResetEvent, 1000, 1000);

我不需要在计时器上调用任何方法;简单地实例化它就足够了。这就是我收到 CA 警告的原因吗?这是我真的只需要抑制错误的情况,还是我错过了什么?

作为旁注,我没有收到应该在计时器上调用 Dispose() 的错误。我不应该得到那个错误吗?

- 编辑 -

如果我将 _timer 设为实例字段,则会收到关于未在其上调用 Dispose() 的错误。为什么静态与实例对此很重要?

4

3 回答 3

4

您收到警告是因为您_timer在分配变量后没有访问该变量。

错误因变量是否为静态而不同的原因正是由于静态变量的性质。静态变量是type的一部分,而不是任何特定对象的一部分。它的生命周期与应用程序域的生命周期相关,而不是任何特定对象的生命周期。由于它的生命周期与应用程序域的生命周期相关联,因此应用程序域的所有者负责定时器的清理。应用程序域的所有者是 CLR 本身,因此 CLR 将清理您的静态计时器。静态分析不会抱怨您没有调用Dispose,因为在卸载应用程序域时将调用计时器的终结器。

如果计时器是一个实例字段,它的生命周期将与拥有它的对象的生命周期相关联。在这种情况下,计时器的清理将由拥有对象负责。在 C# 中,此类对象成员清理是使用 Disposal 模式执行的。如果您还没有实现该模式(通过实现IDisposable)VS 静态分析将发出警告。

话虽如此,计时器是IDisposable. 它们很特别,因为即使您“使用”计时器(通过在其回调中执行代码),您也不会访问计时器对象本身。因此,您可能会倾向于将Timer类视为一种服务。也就是说,你可能认为Timer构造函数更像是一个RegisterForPeriodicCallbacks方法。那是错的。 Timer是一个对象,在 C# 中你必须这样对待它。您必须将其Timer视为具有生命周期的对象,并且由其他对象确定。

如果您希望计时器的生命周期与应用程序的生命周期相关联,那么您应该创建一个类型为静态变量System.Timers.Timer而不是System.Threading.Timer. 当您希望计时器开始计时,只需调用其Start方法即可。

如果您希望计时器的生命周期与某个其他对象的生命周期相关联,那么您应该将它作为一个字段存储在该其他容器对象中,并确保在容器对象上正确实现 Disposal 模式。

如果您执行其中任何一项操作,所有静态分析警告都会消失。

于 2012-07-25T21:10:26.370 回答
4

仅初始化字段不考虑使用它。你需要实际使用它:)

关于您的“编辑”,您永远不应该处理静态对象,否则将来尝试访问它时会出现问题。这就是为什么警告如你所说的那样有效。

于 2012-07-25T20:32:19.820 回答
0

假设您使用的是 System.Windows.Forms.Timer,我认为此警告还会引发另一个问题。忽略此警告或删除您的_timer变量是安全的。但是,当您的应用程序退出时,计时器将继续运行。你可能不想要那个。我建议通过禁用计时器并可能在退出时将其处置来使用此变量。

于 2012-07-25T20:42:56.853 回答