UWP后台任务5次后没有运行

时间:2017-03-09 00:43:46

标签: c# uwp windows-10 windows-10-universal

我正在关注https://docs.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task文档以创建一个后台任务,每15分钟运行一次并ping服务。

  1. 使用实现IBackgroundTask

    的公共密封类创建了一个Windows运行时组件项目
    namespace PeriodicBackgroundTask
    {
        public sealed class FifteenMinutePeriodicTimer : IBackgroundTask
        {
            private static readonly FileLogWriter mWriteLogToFile = new FileLogWriter();
            public FifteenMinutePeriodicTimer() { }
    
            public void Run(IBackgroundTaskInstance taskInstance)
            {
                try
                {
                    taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
                    mDeferral = taskInstance.GetDeferral();
                    mWriteLogToFile.log("Starting periodic timer at " + DateTime.Now.ToString());
    
                    // Calling method to do a Post call to a service.
    
                    mWriteLogToFile.log("Finishing periodic timer at " + DateTime.Now.ToString());
                }
                catch (Exception ex)
                {
                    mWriteLogToFile.log("Fifteen Minute periodic timer failed.", ex);
                }
                finally
                {
                    // Adding some buffer for async processes to finish.    
                    Task.Delay(TimeSpan.FromSeconds(15)).Wait();
                    mDeferral.Complete();
                }
            }
    
            private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
            {
                mWriteLogToFile.log("Fifteen minute periodic timer is canceled. {0}", reason.ToString());
            }
        }
    }
    
  2. 在UWP应用程序的Package.appmanifest文件中输入

    <Extension Category="windows.backgroundTasks" EntryPoint="PeriodicBackgroundTask.FifteenMinutePeriodicTimer">
      <BackgroundTasks>
        <Task Type="systemEvent" />
        <Task Type="timer" />
      </BackgroundTasks>
    </Extension>
    
  3. 在App.xaml.cs中的OnLaunched方法开头注册计时器

    public async static Task RegisterBackgroundTask()
    {
        foreach (var task in BackgroundTaskRegistration.AllTasks)
        {
            if (String.Equals(task.Value.Name, TASK_NAME))
            {
                mWriteLogToFile.log("Old version of fifteen minute periodic timer found. Unregistering it.");
                BackgroundExecutionManager.RemoveAccess();
                // Unregistering so that any update in Background task can be applied.
                task.Value.Unregister(true);
                break;
            }
        }
        BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
        if (backgroundAccessStatus == BackgroundAccessStatus.DeniedByUser ||
        backgroundAccessStatus == BackgroundAccessStatus.DeniedBySystemPolicy)
        {
            mWriteLogToFile.log("Fifteen minute periodic timer registration failed, due to Request access status.");
            return;
        }
    
        BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
        builder.Name = TASK_NAME;
        builder.TaskEntryPoint = "PeriodicBackgroundTask.FifteenMinutePeriodicTimer";
        builder.SetTrigger(new TimeTrigger(15, false));
        builder.CancelOnConditionLoss = false;
    
        var backgroundTask = builder.Register();
        if (backgroundTask != null)
        {
            mWriteLogToFile.log("Fifteen minute periodic timer registration SUCCESSFUL.");
        }
        else
        {
            mWriteLogToFile.log("Fifteen minute periodic timer registration FAILED.");
        }
    }
    
  4. 安装应用程序后,FifteenMinuteBackgroundTimer运行5或6次。有时5,有时6.当我尝试使用Visual Studio调试任务时,我可以调试它。我不确定,为什么FifteenMinuteBackgroundTimer在5次运行后死亡。有人可以告诉我如何调试这个问题?

    更多信息:

    Windows Build:1607
    Microsoft.NETCore.UniversalWindowsPlatform:5.1.0

2 个答案:

答案 0 :(得分:4)

  

有人可以告诉我如何调试此问题?

注册后台任务后,您将在Lifecycle Events工具栏的下拉列表中找到后台任务。在后台任务上设置断点,然后单击工具栏中的背景名称,visual studio将触发后台任务,您可以进行调试。更多详情请参阅Debug a background task

enter image description here

  

为什么FifteenMinuteBackgroundTimer在5次运行后死亡。

如果你在后台任务中运行任何异步代码,那么你的后台任务需要使用deferral.It好像你创建了延迟实例但没有从IBackgroundTaskInstance推迟。所以你可能需要先推迟推迟。

public void Run(IBackgroundTaskInstance taskInstance)
{
    mDeferral = taskInstance.GetDeferral();
    ...
    mDeferral.Complete();       
}

您可能不需要Task.Delay(TimeSpan.FromSeconds(15)).Wait();为异步进程添加一些缓冲区来完成,因为延迟可以帮助您完成此操作。后台任务总共只能运行30s,实际上运行时间可能只有25s,如果在后台设置延迟任务可能导致无法完成任务并强行关闭。

答案 1 :(得分:1)

您很可能遇到两项与电力相关的政策。

  1. 定期计时器触发器被视为机会主义。根据在后台使用多少能源(虽然没有通电和屏幕关闭),您的任务可能不会被激活,以节省其他关键用户活动的能量(如接收短信,推送或来电)。 要验证这是否是您遇到的情况:您可以在应用程序“面板”的“settings-&gt; system-&gt; battery-&gt; battery by battery”面板中将应用程序切换为“始终允许”。
  2. 您还提到,如果屏幕关闭,当您的触发器运行时,网络功能不起作用。在备用系统中,您需要将IsNetworkRequested指定为触发器注册的一部分,以便系统在任务期间将网络接口置于完全操作模式。 请参阅此处的文档:https://docs.microsoft.com/en-us/uwp/api/Windows.ApplicationModel.Background.BackgroundTaskBuilder