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

时间:2017-03-22 10:25:36

标签: c# windows-runtime windows-phone-8.1 background-task

我的Windows Phone 8.1应用程序中的计时器后台任务仅在应用程序从Visual Studio以调试模式运行时被触发。但是,如果我启动甚至调试二进制而不调试它不起作用,不是在15分钟之后,而不是几个小时之后。我在Windows Phone 8.1模拟器和诺基亚lumia 920上测试了它 - 结果相同:在调试会话中它可以工作(它是由系统触发的,我可以从Debug Location工具栏手动启动),但是当手动启动app时没有任何反应。

我也有windows store app,时间后台任务也很好用。

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

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

    <Extension Category="windows.backgroundTasks" EntryPoint="data.TimerHandler">
            <BackgroundTasks>
                    <Task Type="timer" />
            </BackgroundTasks>
    </Extension>
    
  2. 使用此类方法(以及其他方式)在名称空间“data”类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'(我在主应用程序中用于类MyTimerManager的命名空间) 添加了类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组件项目的引用。

  5. 使用相同的命名空间非常重要:在我的Windows Store 8.1应用程序后台任务在我意识到之前没有被解雇。在MSFT文档中没有一个关于它的单词!

    每个应用程序启动我调用setupAlarm()并在日志中看到任务的名称(一切都很好)。但是没有任何事情发生 如果我手动启动此任务(从Lifecircle Events控件),我会看到我的通知。我在几个月前写这段代码的时候记得很奇怪,我看到了通知。我用msft docs检查了一切,但一切似乎都很好。我还应该做些什么来解决任务呢?

1 个答案:

答案 0 :(得分:0)

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

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

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