UWPのバックグラウンドタスクとフォアグラウンドの処理を連携させるために、IBackgroundTaskRegistrationのProgressイベントとCompletedイベントが定義されています。
例えば、TimerTaskという名前のバックグラウンドタスクのProgressイベントとCompletedイベントを購読するには以下のようになります。
using System; using System.Linq; using Windows.ApplicationModel.Background; using Windows.Storage; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; // 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してくださいnamespace App10 { /// <summary>/// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。/// </summary>publicsealedpartialclass MainPage : Page { public MainPage() { this.InitializeComponent(); } protectedoverridevoid OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); var task = BackgroundTaskRegistration.AllTasks .First(x => x.Value.Name == "TimerTask") .Value; task.Progress += this.Task_Progress; task.Completed += this.Task_Completed; } private async void Task_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args) { await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { this.TextBlock.Text = $"{args.Progress}%"; }); } private async void Task_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) { await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { this.TextBlock.Text = (string)ApplicationData.Current.LocalSettings.Values["TimerTask"]; }); } } }
画面にTextBlockという名前のTextBlockを置いている前提のコードになります。ProgressイベントではそのままProgressの状態を表示して、CompletedではApplicationData.Current.LocalSettingsを経由してバックグラウンドタスクからのデータを表示しています。
バックグラウンドタスク側は以下のような実装になっています。
using System; using Windows.ApplicationModel.Background; using Windows.Storage; using Windows.System.Threading; namespace RuntimeComponent1 { publicsealedclass TimerTask : IBackgroundTask { private BackgroundTaskDeferral Deferral { get; set; } privateuint Progress { get; set; } publicvoid Run(IBackgroundTaskInstance taskInstance) { this.Deferral = taskInstance.GetDeferral(); ThreadPoolTimer.CreatePeriodicTimer(timer => { if (this.Progress == 100) { this.Deferral.Complete(); timer.Cancel(); ApplicationData.Current.LocalSettings.Values["TimerTask"] = DateTime.Now.ToString(); return; } taskInstance.Progress = this.Progress; this.Progress += 10; }, TimeSpan.FromSeconds(1)); } } }
タイマーでカウントアップして最後にApplicationData.Current.LocalSettingsにデータを書き込んで終了しています。
バックグラウンドタスクの登録はApp.xaml.csのOnLaunchedメソッドで以下のコードを実行しています。
foreach (var t in BackgroundTaskRegistration.AllTasks) { t.Value.Unregister(true); } var task = BackgroundTaskRegistration.AllTasks .FirstOrDefault(x => x.Value.Name == "TimerTask") .Value; if (task == null) { var tb = new BackgroundTaskBuilder(); tb.Name = "TimerTask"; tb.TaskEntryPoint = "RuntimeComponent1.TimerTask"; tb.SetTrigger(new TimeTrigger(15, false)); task = tb.Register(); }
Package.appxmanifestへタイマーとしてバックグラウンドタスクの宣言を追加するのを忘れずに。
Tipsバックグラウンドタスクのデバッグ
デバッグの場所のライフサイクルイベントから、バックグラウンドタスクのキックが出来ます。