タイマーイベントについて考えてみる

2022年8月23日

Event は、ユーザーが何か処理を開始したいときに、イベントというきっかけでメソッドを呼び出す仕組みです。

次のコードは、Windows FormプログラムのTimerイベントの擬似コードです。

using System;
using System.Threading;
namespace EventTest
{
    delegate void Handler();
    class Timer
    {
        public int Interval { get; set; }
        public void Start()
        {
            Console.WriteLine("タイマースタート");
            Thread.Sleep(Interval);
        }
        public void Stop()
        {
            Console.WriteLine("タイマーストップ");
        }
        public event Handler Tick;
        public void OnTick()
        {
            Tick();
        }
    }
    class TimerController
    {
        Timer[] timers;
        public TimerController(int count)
        {
            timers = new Timer[count];
            for (int i = 0; i < count; i++)
            {
                timers[i] = new Timer();
            }
        }
        public void SetTimeout(Action str, int interval, int channel)
        {
            timers[channel].Interval = interval; // ミリ秒単位で指定
            timers[channel].Start();
            timers[channel].Tick += () => str();
            timers[channel].Stop();
        }
        public void TimerStart(int channel)
        {
            timers[channel].OnTick();
        }
    }
    class Program
    {
        static int interval = 1000;
        static int channel = 0;
        static void Main(string[] args)
        {
            var tc = new TimerController(5);
            Action show = ShowInterval;
            show += ShowChannel;
            tc.SetTimeout(show, interval, channel);
            tc.TimerStart(channel);
        }
        static void ShowInterval()
        {
            Console.WriteLine($"{interval}ミリ秒後、 タイマーが呼ばれました");
        }
        static void ShowChannel()
        {
            Console.WriteLine($"チャネル[{channel}]の、 タイマーが呼ばれました");
        }
    }
}

複数のタイマーの作成をMainメソッド側で設定した場合

using System;
using System.Threading;
namespace EventTest
{
    delegate void Handler();
    // タイマークラス。イベントハンドラ。
    class TimerEvent
    {
        public event Handler Tick;
        public void OnTick()
        {
            Tick();
        }
    }
    class Timer
    {
        public int Interval { get; set; }
        // 複数タイマーを宣言
        public TimerEvent timerEvents = new TimerEvent();
        public void SetTimer(Action str, int interval)
        {
            Interval = interval;
            timerEvents.Tick += () => str();
        }
        public void Start()
        {
            Console.WriteLine("タイマースタート");
            Thread.Sleep(Interval);
        }
        public void Stop()
        {
            Console.WriteLine("タイマーストップ");
        }
        public void OnTick()
        {
            timerEvents.OnTick();
        }
    }
    class Program
    {
        static int number = 0;
        static int count = 5;
        static int interval = 1000;
        static void Main(string[] args)
        {
            var timer = new Timer[count];
            for (int i = 0; i < timer.Length; i++)
            {
                timer[i] = new Timer();
            }
            //Actionデリゲート(引数なし、戻り値なしのメソッド)の変数に代入
            Action show = ShowInterval;
            // さらにメソッドを追加
            show += ShowChannel;
            // イベントのセット
            timer[number].SetTimer(show, interval);
            timer[number].Start();
            // イベント発生
            timer[number].OnTick();
            timer[number].Stop();
        }
        static void ShowInterval()
        {
            Console.WriteLine($"{interval}ミリ秒後、 タイマーが呼ばれました");
        }
        static void ShowChannel()
        {
            Console.WriteLine($"[{number}]番目の、 タイマーが呼ばれました");
        }
    }
}

C#

Posted by hidepon