[ストアアプリ][入門] Step57. バックグラウンドタスクを作成する ~その3~

前回は、バックグラウンドタスクを利用するための設定を行いました。

今回は、前々回作成したIBackgroundTaskのRunメソッドの実装と、トリガーの作成を行っていきます。


今回は、タイムゾーンが変更されたときにバックグラウンドタスクを起動させるように処理を作成していきます。

最初に「タイムゾーンが変更された」というトリガーをシステムに登録するコードを記述します。

トリガーを登録するタイミングはいろいろとあるかと思いますが、今回示す例ではMainpage.xamlがロードされたときとします。

以下の様にコードを記述します。

VBの例

Imports Windows.ApplicationModel.Background

Private Sub Page_Loaded(sender As Object, e As RoutedEventArgs)
    RegistTrigger()
End Sub

Private Sub RegistTrigger()
    'すでに登録してあるバックグラウンドタスクをいったん削除
    If BackgroundTaskRegistration.AllTasks.Count > 0 Then
        'すべてのバックグラウンドタスクを取得
        For Each Task In BackgroundTaskRegistration.AllTasks
            'タスクの削除
            Task.Value.Unregister(True)
        Next
    End If

    'タイムゾーンの変更をトリガーとして設定する
    Dim trigger = New SystemTrigger(SystemTriggerType.TimeZoneChange, False)
    Dim builder = New BackgroundTaskBuilder()

    builder.Name = "BackgroundTask"
    builder.TaskEntryPoint = "BackgroundTask.Class1"
    builder.SetTrigger(trigger)

    'トリガーの登録
    builder.Register()
End Sub

C#の例

using Windows.ApplicationModel.Background;
using BackgroundTask;

public MainPage()
{
    this.InitializeComponent();

    RegistTrigger();
}

private void RegistTrigger()
{

    // すでに登録してあるバックグラウンドタスクをいったん削除
    if (BackgroundTaskRegistration.AllTasks.Count > 0)
    {
        // すべてのバックグラウンドタスクを取得
        foreach (var task in BackgroundTaskRegistration.AllTasks)
        {
            // タスクの削除
            task.Value.Unregister(true);
        }
    }

    // トリガーを設定する
    var trigger = new SystemTrigger(SystemTriggerType.TimeZoneChange, false);
    var builder = new BackgroundTaskBuilder();

    builder.Name = "BackgroundTask";
    builder.TaskEntryPoint = "BackgroundTask.Class1";
    builder.SetTrigger(trigger);

    // トリガーの登録
    builder.Register();
}

上記では、RegisterTriggerというメソッドの中でトリガーを登録する処理を行っています。

最初に、既に登録済みであるバックグラウンド処理をすべて削除しています。

次に、トリガーの設定を行います。

今回トリガーは、「タイムゾーンの変更時」とします。タイムゾーンの変更はシステムイベントとなります。

タイムゾーンの変更は、WIndowsの日付と時計から変更ができます。日本国内であれば「(UTC+09:00)大阪、札幌、東京)」に設定してあるかと思います。この「タイムゾーンの変更を行ったとき」をトリガーとします。

タイムゾーンの変更

 

タイムゾーンの変更をトリガーとするには、SystemTriggerType.TimeZoneChangeをSystemTriggerとして作成し、BackgroundTaskBuilderクラスでトリガーの登録を行います。

コード中のbuilder.Nameには任意の名前を登録します。トリガーにはわかりやすい名前を付けておきましょう。

次に、実際にトリガー発生時の処理をどこで行うか、つまりエントリポイントを指定します。

これは、前々回作成したRunメソッドのある場所となるので、builder.TaskEntryPointに”BackgroundTask.Class1”を指定します。

最後にbuilder.Register()メソッドでトリガーを登録します。


今度はトリガー発生時の処理を作成します。

ソリューションエクスプローラーで前々回作成したプロジェクトのClass1にあるRunメソッドを以下の様に編集します。

IBackgroundTaskインターフェースのRunメソッドは、バックグラウンドタスクのトリガー条件が満たされた場合に実行されるメソッドです。

よって、トリガー発生時に起動したい処理はRunメソッドの中に記述します。

以下にコード例を示します。

VBの例

Public Sub Run(taskInstance As IBackgroundTaskInstance) Implements IBackgroundTask.Run
    Dim deferral = taskInstance.GetDeferral()

    'トースト通知を行う設定
    Dim toastTemplate = ToastTemplateType.ToastText02
    Dim toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate)

    Dim toastTextElements = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(toastXml.CreateTextNode("通知"))
    toastTextElements(1).AppendChild(toastXml.CreateTextNode("タイムゾーンが変更されました"))


    Dim toast = New ToastNotification(toastXml)
    toast.ExpirationTime = DateTimeOffset.UtcNow.AddSeconds(30)

    ToastNotificationManager.CreateToastNotifier().Show(toast)

    deferral.Complete()
End Sub

C#の例

public void Run(IBackgroundTaskInstance taskInstance)
{
    BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

    ToastTemplateType toastTemplate = ToastTemplateType.ToastText02;
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(toastXml.CreateTextNode("通知"));
    toastTextElements[1].AppendChild(toastXml.CreateTextNode("タイムゾーンが変更されました"));


    ToastNotification toast = new ToastNotification(toastXml);
    toast.ExpirationTime = DateTimeOffset.UtcNow.AddSeconds(30);
    toast.Failed += toast_Failed;

    ToastNotificationManager.CreateToastNotifier().Show(toast);

    deferral.Complete();
}

上記のコードを見ていきましょう。

最初のBackgroundTaskDeferralクラスのGetDeferralメソッドおよび、最後のCompleteメソッドは、Runメソッドの実行が完了した場合でも非同期で処理が継続しているということを通知するためのものです。

Runメソッドの処理が完了すると、「バックグラウンドタスクは完了した」ことになります。しかし、この処理が非同期で行われる場合には、Runメソッドが終了して呼び出し元に戻ったても、まだバックグラウンドタスクが終了していないことがあります。この状態でタスクのインスタンスが削除されてしまうと、非同期処理も強制で終了となってしましいます。そこでGetDeferralメソッドとCompleteメソッドが必要になるというわけです。

それ以外の処理については、以前の記事で紹介したトースト通知を利用しているだけです。

Runメソッドが起動すると(タイムゾーンが変更されたとき)、「タイムゾーンが変更されました」というトースト通知が行われます。

実行例

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.