3
votes

I am working on a Windows Phone 8.1 application which registers a background task timer trigger for hourly operation. So essentially, the background task wake up every 60 minutes and does some operation.

My question is that, when the background task is in progress, if the user wakes up the application, is there a way that we can show the user what is happening in the background task process?

I understand that they are two different processes. I am using a Silverlight 8.1 project for the foreground application and a managed windows runtime project for the background task. I am registering the background task using the silverlight application but i am in a dark now thinking about how to create a communication bridge between these two processes.

Any clues ? Is this even possible ?

2

2 Answers

5
votes

Here are some ideas (or info) about communication between the app and its background tasks.

  • You could use the Progress and Completed events of the IBackgroundTaskRegistration object. You can get that object using BackgroundTaskRegistration.AllTasks - this property returns the list of background tasks registered by the app. Each time the app runs, you'll have to subscribe to these events.

    From the background task you can set the Progress property of the IBackgroundTaskInstance object to some UInt32 value, and the app will receive the event. Maybe you can encode what you need in that number. For example: 1 means that the task is initializing, 2 - the task is doing WorkA, and so on...

  • Both processess have access to the same files, so maybe you can use that for something.

  • Use Mutex to sync the execution of code between the two processes.

That's all I can think of right now. I hope it helps.

P.S. I haven't really tried those events, but they seem like they might be useful.

1
votes

I have already did some POC on commnication b/w Background Task and the app it self. I was using windows universal app but it will work in silverlight phone app too.

private IBackgroundTaskRegistration timeZoonChangeTask;
    public MainPage() 
    {
        this.InitializeComponent();

        NavigationHelper nvHelper = new NavigationHelper(this);
        IReadOnlyDictionary<Guid, IBackgroundTaskRegistration> allTasks = BackgroundTaskRegistration.AllTasks;
        if (allTasks.Count() == 0)
        {
            lblMessage.Text = "No Task is registered at the moment";
        }
        else//Task already registered
        {
            lblMessage.Text = "Timezoon Task is registered";
            this.GetTask();
        }
    }

    /// <summary>
    /// Time zoon task registration.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        await BackgroundExecutionManager.RequestAccessAsync();

        BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
        taskBuilder.Name = "MyBackgroundTask";

        SystemTrigger systemTrigger = new SystemTrigger(SystemTriggerType.TimeZoneChange, false);
        taskBuilder.SetTrigger(systemTrigger);

        taskBuilder.TaskEntryPoint = typeof(MyBackgroundTask.TheTask).FullName;
        taskBuilder.Register();
        lblMessage.Text = "Timezoon Task is registered";


        this.GetTask();

    }

/// Get registered task and handel completed and progress changed events.
    /// </summary>
    private void GetTask()
    {
        var timeZoonChangeTask = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault();
        timeZoonChangeTask.Completed += timeZoonChangeTask_Completed;
        timeZoonChangeTask.Progress += timeZoonChangeTask_Progress;

    }

    /// <summary>
    /// raised when task progress is changed app is active
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    void timeZoonChangeTask_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args)
    {
        this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            lblTaskProgress.Text = args.Progress.ToString() + "%";
            recProgress.Width = 400 * (double.Parse(args.Progress.ToString()) / 100);
        });
        //this.Dispatcher.BeginInvoke(() =>
        //    {

        //    });
    }

    /// <summary>
    /// Raised when task is completed and app is forground
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    void timeZoonChangeTask_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
    {
        this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
          {
              lblMessage.Text = "Task Excecution is completed";
          });
    }

and below is the task class

public sealed class TheTask:IBackgroundTask
{
    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        ///Get Deferral if we are doing aysnc work. otherwise it will not work. 
        //Always get deferral it will not harm.
        var deferral = taskInstance.GetDeferral();


        taskInstance.Canceled += taskInstance_Canceled;

        for (uint i = 0; i < 10; i++)
        {
            taskInstance.Progress = i + 10;
            await Task.Delay(2000);
        }

        //Write last run time somewhere so the gorground app know that at when last time this backgournd app ran.

        ///Set this progress to show the progesss on the forground app if it is running and you want to show it.
        taskInstance.Progress = 0;

        deferral.Complete();
    }

    void taskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
    {

    }
}