著作一覧 |
.NETにはTimerクラスが3つあって、WinForm用のはどうもいまいち様子がわからない。
System.Timers.Timerについては、石塚さんが言及されている。
最後のSystem.Threading.Timerは、matarilloさんによればGCされてしまうとMSDNに明記されているとのことだ。確かにそうだ。
Timer を使用している間は、このクラスへの参照を保持しておく必要があります。他のマネージ オブジェクトと同様、まったく参照されていない場合、Timer はガベージ コレクションの対象となります。Timer がアクティブであっても、ガベージ コレクションの対象から除外されることはありません。
というわけでおもしろそうなのでSystem.Threading.Timerを試した。
var timer = new System.Threading.Timer((o) => MessageBox.Show("timer"), null, 10000, 5000); var timer2 = new System.Threading.Timer((o) => System.GC.Collect(), null, 8000, System.Threading.Timeout.Infinite);
期待通りにメッセージボックスは表示されない。あるいは、timer2を10秒以上に取れば、2回目以降、20秒以上に取れば3回目以降は表示されなくなる。
ということは、System.Threading。Timerは、上記のような使い方、つまり自動変数として定義して放り投げるのは、だめだということだ(が、後始末は不要なので、便利は便利。とは言え、イベントを出さずに消えてなくなるのはいやだな)。
まあ、WindowsFormで利用する場合は、スレッド間マーシャリングを考えなくても良いので、Timerをインスタンス変数に持って使うのが良いだろう(というか、保持しておかなければDisposeできない。アプリケーションと同じ寿命を持つことが前提ならば後始末を考えなくても良いので自動変数のほうが余分なインスタンス変数名を定義する必要がないので良いかも。
ジェズイットを見習え |