Windows phone 应用程序 8.1 - 后台任务未启动

Windows phone app 8.1 - Background Task is not launched

我的 windows phone 8.1 应用程序中的计时器后台任务仅在应用程序 运行 从 visual studio 处于调试模式时被触发。但是,如果我在没有调试的情况下启动甚至调试二进制文件,它就不起作用,15 分钟后,几个小时后都不会。我在 windows phone 8.1 模拟器和 nokia lumia 920 上测试了它 - 结果相同:在调试会话中它工作(它由系统触发,我可以从调试位置工具栏手动触发它),但是当应用程序手动启动时没有任何反应。

我也有 windows 商店应用程序,时间后台任务在其中运行良好。

为了使用后台任务,我执行了以下操作:

  1. 在我的 wp8.1 项目清单中,我添加了:

    <Extension Category="windows.backgroundTasks" EntryPoint="data.TimerHandler">
            <BackgroundTasks>
                    <Task Type="timer" />
            </BackgroundTasks>
    </Extension>
    
  2. 在命名空间 'data' class MyTimerManager 中使用此类方法(以及其他方法)创建:

    public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint, string taskName, IBackgroundTrigger trigger, IBackgroundCondition condition)
    {
        foreach (var cur in BackgroundTaskRegistration.AllTasks)
        {
            if (cur.Value.Name == taskName)
                return (BackgroundTaskRegistration)(cur.Value);
        }
        var builder = new BackgroundTaskBuilder();
        builder.Name = taskName;
        builder.TaskEntryPoint = taskEntryPoint;
        builder.SetTrigger(trigger);
        if (condition != null)
            builder.AddCondition(condition);
        BackgroundTaskRegistration task = null;
        try
        {
            task = builder.Register();
        }
        catch (Exception e)
        {
            LogError(e);
        }
        return task;
    }
    
    public static bool UnRegisterBackgroundTask(string taskName)
    {
        foreach (var cur in BackgroundTaskRegistration.AllTasks)
        {
            if (cur.Value.Name == taskName)
            {
                ((BackgroundTaskRegistration)cur.Value).Unregister(false);
                return true;
            }
        }
        return false;
    }
    
    public static void setupAlarm()
    {
        TimeTrigger timerTrigger = new TimeTrigger(30, false);
        string entryPoint = "data.TimerHandler";
        string taskName = "TimerHandler task";
        UnRegisterBackgroundTask(taskName);//just in case
        BackgroundTaskRegistration task = RegisterBackgroundTask(entryPoint, taskName, timerTrigger, null);
        Log("RegisterBackgroundTask: " + (task!=null ?task.Name:null));
    }
    
  3. 创建了 winrt 组件项目,将其默认命名空间设置为 'data'(我在主应用程序中用于 class MyTimerManager 的相同命名空间) 添加了 class TimerHandler:

    namespace data
    {
    public sealed class  TimerHandler : IBackgroundTask
    {
        BackgroundTaskDeferral deferral = null;
    
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            deferral = taskInstance.GetDeferral();
            await BackgroundExecutionManager.RequestAccessAsync();
            await backgroundTimerCallAsync();
            deferral.Complete();
        }
        public static async Task backgroundTimerCallAsync()
        {
            NotificationSender ns = new NotificationSender(false, null, null);
            ns.sendNotification("Timer task msg");//my code which sends notification
        }
    }
    }
    
  4. 在我的 wp8.1 项目中添加了对 winrt 组件项目的引用。

使用相同的命名空间非常重要:在我意识到这一点之前,我的 Windows Store 8.1 应用程序后台任务没有被触发。在 MSFT 文档中只字未提!

每次启动应用程序时,我都会调用 setupAlarm() 并在日志中看到任务名称(一切正常)。但是什么也没有发生。 如果我手动启动此任务(从 Lifecircle Events 控件),我会看到我的通知。我记得一个月前编写此代码时看到通知的奇怪事情。我已经用 msft 文档检查了所有内容,但一切似乎都很好。我还应该怎么做才能触发任务?

在某些示例中,我发现您应该在注册任务之前调用 RequestAccessAsync!成功了。

之前意味着你必须等到 RequestAccessAsync 完成,我不得不在同步代码中调用它,所以我这样做了:

    BackgroundExecutionManager.RequestAccessAsync.AsTask().ContinueWith(
        (t) => registerMyTasks()).ConfigureAwait(false);