Windows Phone 8.1后台任务和前台应用程序通信

时间:2014-05-27 19:57:22

标签: windows-runtime windows-phone windows-8.1 windows-phone-8.1

我正在开发一个Windows Phone 8.1应用程序,该应用程序为每小时操作注册一个后台任务计时器触发器。基本上,后台任务每60分钟唤醒并执行一些操作。

我的问题是,当后台任务正在进行时,如果用户唤醒了应用程序,是否有办法向用户显示后台任务流程中发生了什么?

我知道它们是两个不同的过程。我正在为前台应用程序使用Silverlight 8.1项目,为后台任务使用托管的Windows运行时项目。我正在使用silverlight应用程序注册后台任务,但我现在正在考虑如何在这两个进程之间建立通信桥梁。

任何线索?这甚至可能吗?

2 个答案:

答案 0 :(得分:5)

以下是有关应用与其后台任务之间通信的一些想法(或信息)。

  • 您可以使用IBackgroundTaskRegistration对象的“进度”和“已完成”事件。您可以使用BackgroundTaskRegistration.AllTask​​s获取该对象 - 此属性返回应用程序注册的后台任务列表。每次应用程序运行时,您都必须订阅这些事件。

    从后台任务中,您可以将IBackgroundTaskInstance对象的Progress属性设置为某个UInt32值,应用程序将接收该事件。也许你可以用这个数字编码你需要的东西。例如:1表示任务正在初始化,2 - 任务正在进行WorkA,依此类推......

  • 这两个进程都可以访问相同的文件,所以也许你可以将它用于某些东西。

  • 使用Mutex同步两个进程之间的代码执行。

这就是我现在所能想到的。我希望它有所帮助。

P.S。我没有真正尝试过那些事件,但看起来它们似乎很有用。

答案 1 :(得分:1)

我已经在通信b / w后台任务和自己的应用程序上做了一些POC。我正在使用Windows通用应用程序,但它也适用于silverlight手机应用程序。

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";
          });
    }

以下是任务类

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)
    {

    }
}