それでは,前回お伝えした通り,タイマークラスを作成していきます。
タイマークラスの作成
次のようにコーディングします。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace NDDD.WinForm.BackgroundWorkers { internal static class LatestTimer { private static Timer _timer; private static bool _isWork = false; static LatestTimer() { _timer = new Timer(Callback); } internal static void Start() { _timer.Change(10000, 10000); } internal static void Stop() { _timer.Change(Timeout.Infinite, Timeout.Infinite); } private static void Callback(object o) { if (_isWork) { return; } try { _isWork = true; //ここで定期的に実施する処理を書く } finally { _isWork = false; } } } }
アクセス修飾子はWinFormプロジェクトでしか使用しないので,Internalとします。あと,アプリケーションに1つでよいので,staticにします。Timer型の_timer変数はSystem.Threading.Timerを使います。UsingにSystem.Threadingがあることに注意してください。Windowsフォームの画面デザインで貼り付けできるWindowsタイマーではありません。Windowsタイマーは同期で動作しますが,System.Threading.Timerは非同期で動作します。バックグラウンドで動作させるには非同期で動作させる必要があるので,こちらを使用します。
コンストラクタ
コンストラクタの_timerをnewしている部分でCallbackを指定しています。Callbackはタイマーが動作したときに呼ばれるメソッドです。
Startメソッド
Startメソッドは_timer.Changeでタイマー間隔を指定します。10秒後から10秒間隔といった感じで,2つのミリ秒の値をセットします。
Stopメソッド
タイマーを停止したときに止めたい処理を書いておきます。
Callbackメソッド
タイマーが通知されたときの処理を書きます。
_isWork変数を使っているのは,タイマー処理中に,次のタイマー処理が来た場合は,処理をスキップするためです。スレッドタイマーは,タイマーを止めない限り,処理中でもどんどん次のタイマーイベントが通知されます。処理中にもう一度処理されるとバグの元になるので,処理中ならスキップするようにします。スキップするのが理想的でない場合は,タイマー処理に入った時点でタイマーを停止させて,抜けるときにタイマーを開始させるように実装してもいいでしょう。
「ここで定期的に実施する処理を書く」とコメントしている部分で処理を書きます。多くの場合はドメイン層やインフラストラクチャー層の呼び出しになると思います。