我在我的应用程序的一个类中使用System.Timers.Timer类。 我知道Timer类具有继承自实现IDisposable接口的父Component类的Dispose方法。 在我的应用程序生命周期中,下面创建的类实例多次;他们每个人都有一个Timer类的实例,它在类的生命周期中连续生成Elapsed事件。 我应该在使用Timer类来配置计时器对象的类中实现IDisposable接口吗? (我见过的代码完全没有这样做)。 如果我使用下面的类,我担心一些非托管资源将不会被释放:
SomeClass someClass = new SomeClass();
someClass.DoSomething();
someClass = null;
班级:
using System.Timers;
public class SomeClass
{
private Timer m_timer;
public SomeClass()
{
m_timer = new Timer();
m_timer.Interval = 1000;
m_timer.Elapsed += new ElapsedEventHandler(m_timer_Elapsed);
m_timer.AutoReset = false;
m_timer.Start();
}
public void DoSomething()
{
}
private void m_timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
//Do some task
}
catch (Exception ex)
{
//Ignore
}
finally
{
if (m_timer != null)
{
//Restart the timer
m_timer.Enabled = true;
}
}
}
}
答案 0 :(得分:29)
一般来说,您应该始终处置一次性资源。在你上面概述的情况下,我当然会期待。如果在实现计时器的类上实现IDisposable,则可以在using语句中使用该类,这意味着在处理类时将显式释放资源。
答案 1 :(得分:20)
我看到你在一年前问过这个问题,但让我投入2美分。因通货膨胀而略少:)。最近我在申请中发现我们没有处理定时器。我们有一个对象集合,每个对象都有一个计时器。当我们从集合中删除项目时,我们认为它应该被垃圾收集。出于某些原因,定时器不是这样。我们不得不在集合中的对象上调用dispose,以便在对象实际上被垃圾收集之前摆脱计时器。
答案 2 :(得分:5)
我使用的经验法则是制作任何具有IDisposable对象的东西,IDisposable本身(并且只有在显式调用Dispose时才处理子对象)
在Joe Duffy's blog上对IDisposable进行了很好的讨论以及代码示例,这些示例与我的优秀Framework Design Guidelines本书副本中的代码示例非常相似
答案 3 :(得分:4)
计时器必须处理掉,或者在你“完成”它之后会持续射击一段时间。但是由于线程问题,在您处理它之后它可能仍会短时间激活!
答案 4 :(得分:2)
我猜测计时器对象会创建或使用工作线程来触发计时器事件。 dispose调用将释放线程和与之关联的资源。如果是这种情况,那么调用dispose是个好主意,这样你就不会有未使用的线程停留太长时间。
答案 5 :(得分:2)
通过实现idisposable,您将能够整理任何也实现idisposable的内部资源,例如您的计时器。
此外,您可以更改您的呼叫代码以使用使用陈述。
using (SomeClass someClass = new SomeClass())
{
someClass.DoSomething();
}
答案 6 :(得分:1)
我同意罗兰。
FxCop中有一条规则,它找到包含Disposable对象的类,但没有正确实现IDisposable。