web-dev-qa-db-ja.com

アプリケーションで使用する場合、System.Timers.Timerを破棄する必要がありますか?

アプリケーションのクラスの1つでSystem.Timers.Timerクラスを使用しています。 Timerクラスには、IDisposableインターフェイスを実装する親Componentクラスから継承されたDisposeメソッドがあることを知っています。以下のクラスのインスタンスは、アプリケーションのライフサイクル中に何度も作成されます。それぞれに、クラスのライフサイクル中に継続的にElapsedイベントを生成するTimerクラスのインスタンスがあります。 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;
            }
        }
    }
}
40
Roman Shumikhin

一般的に言って、あなたは常に使い捨ての資源を処分するべきです。あなたが上で概説した場合には、私は確かに探しているでしょう。タイマーを実装するクラスにIDisposableを実装すると、usingクラスでクラスを使用できます。つまり、クラスが破棄されると、リソースが明示的に解放されます。

31
flesh

1年前にこの質問をされたようですが、2セント相当の金額を投入させていただきます。インフレのために少し少ない:)。最近、アプリケーションでタイマーを破棄していないことがわかりました。オブジェクトのコレクションがあり、各オブジェクトにはタイマーがありました。コレクションからアイテムを削除したとき、私たちはそれがガベージコレクションされたはずであると考えました。なぜかタイマーではそうではありません。オブジェクトが実際にガベージコレクションされる前に、タイマーを取り除くために、コレクション内のオブジェクトに対してdisposeを呼び出す必要がありました。

21
uriDium

私が使用する経験則は、IDisposableオブジェクト、IDisposable自体を含むものを作成することです(Disposeが明示的に呼び出された場合にのみ子オブジェクトを破棄します)。

Joe Duffyのブログ でIDisposableについての良い議論があります。また、優れた Framework Design Guidelines の本のコピーと非常によく似たコードサンプルも紹介されています。

5
Rowland Shaw

タイマーは破棄する必要があります。そうしないと、タイマーが「終了」した後もしばらくはタイマーが作動し続けます。ただし、スレッドの問題により、破棄した後も短時間で起動する可能性があります。

4
Ian Ringrose

タイマーオブジェクトは、タイマーイベントを発生させるためにワーカースレッドを作成または使用していると思います。破棄呼び出しは、スレッドとそれに関連付けられたリソースを解放します。その場合は、disposeを呼び出して、未使用のスレッドが長時間ハングアップしないようにすることをお勧めします。

2

Idisposableを実装することで、タイマーなどのidisposableも実装する内部リソースを整理できます。

さらに、usingステートメントを使用するように呼び出しコードを変更することができます。

using (SomeClass someClass = new SomeClass())
{  
someClass.DoSomething();  
}  
2
John

ローランドに同意します。

FxCopには、Disposableオブジェクトを含むクラスを検索するルールがありますが、IDisposableを適切に実装していません。

1
GregC