System.Threading.Timer和CA1823:AvoidUnusedPrivateFields

时间:2012-07-25 20:30:09

标签: c# code-analysis

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

private static Timer _timer;

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

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

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

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

- 编辑 -

如果我让_timer成为一个实例字段,那么我会得到关于不调用Dispose()的错误。为什么静态与实例有关系呢?

3 个答案:

答案 0 :(得分:4)

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

关于“编辑”,你不应该处置静态对象,否则将来尝试访问它时会出现问题。这就是你所说的警告有效的原因。

答案 1 :(得分:4)

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

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

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

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

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

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

如果您执行上述任一操作,所有静态分析警告都将消失。

答案 2 :(得分:0)

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

相关问题