2011-02-24 19 views
8

C#で機能のこのペアを考えてみましょう:このタイマーはメモリから解放されますか?

void func1() { 
    DispatcherTimer tmr = new DispatcherTimer(); 
    tmr.Interval = TimeSpan.FromSeconds(5); 
    tmr.Tick += func2; 
    tmr.Start(); 
} 

void func2(object a, EventArgs b) { 
    // Called every 5 seconds once func1() is called 
} 

関数func1()を呼び出した後、一度、関数func2()はその範囲が制限されているので、私は私のタイマーへの参照を失うことにもかかわらず、それ以降5秒ごとに呼び出され〜func1()。つまり、func1()が呼び出されてからずっと、タイマーは明らかにメモリ内に残っています。

void func2(object a, EventArgs b) { 
    // Called every 5 seconds once func1() is called 

    ((DispatcherTimer)a).Stop() 
} 

タイマーがすぐ後に、ガベージコレクションによってピックアップされるか、またはそれはプログラムが終了するまでメモリに滞在していきます:私は関数func2()にこれを追加する場合、私の質問は、ありますか?それがメモリに残っている場合は、手動でコレクションにマークを付けるにはどうしたらいいですか?

私が持っている第二の質問(あなたが答えたいと思っている場合)は、この状況で正規のタイマーがまったく同じ動作をするか、または私が知るべき重要な違いがあるかどうかです。

ありがとうございます!

答えて

7

Threading.Dispatcherクラスは、アクティブなすべてのDispatcherTimersのリストを保持します。 TickイベントハンドラでStop()を呼び出すと、タイマーはそのリストから削除されます。タイマーへの参照はなくなりました。最終的にはガベージコレクションされます。タイマーをもう一度起動させる方法がないのでどちらも大丈夫です。結局のところ、参照を取得する方法がなくなり、Tickイベントハンドラが最後のショットになりました。

0

thisによれば、ハンドラを停止して削除する必要があります。

0

DispatcherTimerは基本的に新しいスレッドを生成します。そのスコープは通常考えられるように定義することはできません。代わりに、特定の方法でスレッドを削除することもできます。