UWP后台任务在运行5次后停止运行

6

我正在按照https://learn.microsoft.com/zh-cn/windows/uwp/launch-resume/create-and-register-a-background-task文档创建一个后台任务,该任务将每15分钟运行一次并ping一个服务。

  1. Created a Windows Runtime Component project with a public sealed class implementing IBackgroundTask

    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. Entry in UWP application's Package.appmanifest file

    <Extension Category="windows.backgroundTasks" EntryPoint="PeriodicBackgroundTask.FifteenMinutePeriodicTimer">
      <BackgroundTasks>
        <Task Type="systemEvent" />
        <Task Type="timer" />
      </BackgroundTasks>
    </Extension>
    
  3. Registering Timer at the beginning of OnLaunched Method in App.xaml.cs

    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.");
        }
    }
    
安装应用程序后,FifteenMinuteBackgroundTimer运行了5或6次。有时是5次,有时是6次。当我尝试使用Visual Studio调试任务时,我可以进行调试。我不确定为什么FifteenMinuteBackgroundTimer在运行5次后就会停止工作。请问有人可以告诉我如何调试此问题吗?
更多信息:
Windows版本:1607 Microsoft.NETCore.UniversalWindowsPlatform版本:5.1.0
2个回答

4

有人能告诉我如何调试这个问题吗?

在注册后台任务后,您将在生命周期事件工具栏的下拉列表中找到后台任务。在后台任务上设置断点,然后单击工具栏中的后台名称,Visual Studio 将触发后台任务,您可以进行调试。更多详细信息,请参阅 调试后台任务

enter image description here

为什么 FifteenMinuteBackgroundTimer 在运行5次后就挂了。

如果在后台任务中运行异步代码,则需要使用延迟(deferral)。看起来你创建了延迟实例,但没有从 IBackgroundTaskInstance 中获取延迟。因此,你可能需要首先获取延迟。

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

您可能不需要使用 Task.Delay(TimeSpan.FromSeconds(15)).Wait(); 添加一些缓冲时间来等待异步进程完成,因为 deferral 可以帮助您完成这项任务。后台任务最多只能运行30秒,实际运行时间可能只有25秒,如果在后台任务中设置延迟可能会导致无法完成任务并强制关闭。


谢谢您的回复。我尝试了您的建议并取得了一些进展。如果我让设备一直充电并保持屏幕开启,那么定期计时器会运行。然而,如果我锁定屏幕并拔掉充电器,定期计时器就不会运行。 - c2tarun
1
@c2tarun - 你可以进入“设置”,“系统”,“电池”,“按应用程序使用电池”并将你的应用程序更改为“始终运行”。虽然不是理想的解决方案,但这可能会给你一个指示,看看是否是这个问题。 - H H

1
很可能您遇到了与电源相关的两个策略。
1. 周期性定时器触发被视为机会主义。根据后台使用的能量(未接通电源且屏幕关闭时),您的任务可能不会被触发,以便为其他关键用户活动(如接收短信、推送或来电)保留能量。要验证是否遇到了这种情况:您可以在“设置->系统->电池->按应用程序分类”面板中将您的应用程序切换为“始终允许”。
2. 您还提到当屏幕关闭时,触发器运行时网络功能无法正常工作。在待机系统中,您需要在触发器注册中指定IsNetworkRequested,以便系统在您的任务持续时间内将网络接口置于完全操作模式。请参阅此处的文档:https://learn.microsoft.com/en-us/uwp/api/Windows.ApplicationModel.Background.BackgroundTaskBuilder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接