DispatcherTimerを使って定期実行をする


WindowsPhone 7アプリケーション作成にあたって、スライドショーやタイマによる情報更新など
定期的に表示内容を変更したい場面が多々出てきます。
今回は定期的に表示内容(UI)を変更する方法としてDispatcherTimerを紹介します。
定期実行には3種類の方法があります。メリット、デメリットは以下のとおりです。

  1. System.Windows.Threading.DispatcherTimer
    • メリット:UIへのアクセスが可能
  2. System.Timers.Timer
    • メリット:3種類の中で最も時間に正確
    • デメリット:UIへのアクセスは相応の処理が必要
  3. System.Threading.Timer
    • メリット:System.Timers.Timerよりも軽い
    • デメリット:利用するにあたっての設定が多い

今回紹介するDispatcherTimerは他のタイマーと違いUIへのアクセスが可能なため、特別な処理を記述することがなく非常に簡単に利用することができます。

そのDispatcherTimerでよく利用するプロパティとメソッドになります。

DispatcherTimerの主要なプロパティ

メンバ名概要
bool IsEnabledタイマーが実行されているかどうかを示す値を取得または設定します。
TimeSpan Intervalタイマー刻みの間隔の時間を取得または設定します。

DispatcherTimerの主要なメソッド

メソッド名概要
void start()DispatcherTimer を開始します。
void stop()DispatcherTimer を停止します。
続きをご覧ください。

今回はストップウォッチを題材に定期実行について説明していきます。

定期実行で変更したいUI部品の記述

定期実行で表示内容を変更するTextBlockと定期実行のスタート/ストップボタンをXAMLに下記のように記述します。
■MainPage.xaml

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <TextBlock Height="72" HorizontalAlignment="Left" Margin="12,62,0,0" Name="textTime" Text="textTime" VerticalAlignment="Top" Width="228" FontSize="40" />
    <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="246,62,0,0" Name="btnStartStop" VerticalAlignment="Top" Width="160" Click="ClickButton" />
</Grid>

イベント登録とコールバックのメソッドの設定

DispatcherTimerは、登録したコールバックメソッドを一定間隔で呼び出す仕組みです。
DispatcherTimerを利用するために、以下手順をふむ必要があります。

  1. 定期処理の実行間隔を設定する
  2. コールバックで呼び出されるメソッドを登録する

1,定期処理の実行間隔を設定する
実行間隔はTimeSpan構造体で設定を行います。
TimeSpan構造体のよく使うメソッドは下記の表のようになります。

TimeSpan構造体

メソッド名意味
TimeSpan FromDays(double value)指定した日数を表す TimeSpan を返します
TimeSpan FromHours(double value)指定した時間数を表す TimeSpan を返します
TimeSpan FromMinutes(double value)指定した分数を表す TimeSpan を返します
TimeSpan FromSeconds(double value)指定した秒数を表す TimeSpan を返します
TimeSpan FromMilliseconds(double value)指定したミリ秒数を表す TimeSpan を返します

この構造体をIntervalにセットすることで実行間隔を決定することができます。

2,コールバックで呼び出されるメソッドを登録する
EventHandlerで呼び出されるメソッド名を設定しDispacherTimerにセットすることでコールバックで呼び出されるメソッドを登録することができます。

定期実行の間隔を設定、コールバックされるメソッドの指定は下記のサンプルプログラムのように記述します。
■MainPage.xaml.cs

private DispatcherTimer mTimer;
private double mTime = 0.0;

//コンストラクター
public MainPage() {
    initializeComponent();
    mTimer = new DispatcherTimer();
    mTimer.Interval = TimeSpan.FromMilliseconds(100); //100ミリ秒間隔に設定
    mTimer.Tick += new EventHandler(TickTimer);
    textTime.Text = mTime.ToString();
    btnStartStop.Content = "start";
}

void TickTimer(object sender, EventArgs e){
    mTime += 0.1;
    textTime.Text = mTime.ToString("f1");  //mTimeを小数点第一位までを文字列に変換
}

8行目にて定期実行の間隔を100ミリ秒間隔に設定し、9行目でTickイベントによってコールバックされるメソッドの指定を行っています。
これでDispatcherTimerをスタートすると100ミリ秒間隔でTickTimerというメソッドが呼ばれるようになります。
定期実行されるTickTimerは16行目でTextBlockの内容を書き換えています。

ボタンイベントでストップウォッチの開始と停止

ストップウォッチの全体のソースは下記のようになります。
■MainPage.xaml.cs

public partial class MainPage : PhoneApplicationPage {
    private DispatcherTimer mTimer;
    private double mTime = 0.0;

    public MainPage(){
        InitializeComponent();
        mTimer = new DispatcherTimer();
        mTimer.Interval = TimeSpan.FromMilliseconds(100);
        mTimer.Tick += new EventHandler(TickTimer);
        textTime.Text = mTime.ToString();
        btnStartStop.Content = "start";
    }

    private void ClickButton(object sender, RoutedEventArgs e){
        if (mTimer.IsEnabled){
            btnStartStop.Content = "start";
            mTimer.Stop();
        } else {
            btnStartStop.Content = "stop";
            mTime = 0.0;
            textTime.Text = mTime.ToString("f1");
            mTimer.Start();
        }
    }

    void TickTimer(object sender, EventArgs e) {
        mTime += 0.1;
        textTime.Text = mTime.ToString("f1");
    }
}

ボタンのコールバックのメソッド内にある17行目と22行目でDisptcherTImerの開始と停止を行なっています。
DispatcherTimerの状態を15行目で確認し開始を行うか停止を行うかを決定しています。

実際に動かすと以下の図のようになります。

DispatcherTimerサンプルプログラムのストップウォッチ

このサンプルプログラムのようにDispatcherTimerを利用することで別のスレッドからのUIスレッドの定期的なアクセスを行うことなく定期的にUIを変更することができます。

2 Comments