【问题标题】:UWP Background Task not running after 5 timesUWP 后台任务 5 次后未运行
【发布时间】:2017-03-09 00:43:45
【问题描述】:

我正在关注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.");
        }
    }
    

安装应用程序后,FifteenMinuteBackgroundTimer 运行 5 或 6 次。有时 5,有时 6。当我尝试使用 Visual Studio 调试任务时,我能够调试它。我不确定,为什么 FiveMinuteBackgroundTimer 在 5 次运行后死亡。谁能告诉我如何调试这个问题?

更多信息:

Windows 内部版本:1607
Microsoft.NETCore.UniversalWindowsPlatform:5.1.0

【问题讨论】:

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


    【解决方案1】:

    谁能告诉我如何调试这个问题?

    注册后台任务后,您会在生命周期事件工具栏的下拉列表中找到后台任务显示。在后台任务上设置一个断点然后点击工具栏中的后台名称,visual studio会触发后台任务,就可以调试了。更多详情请参考Debug a background task

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

    如果您在后台任务中运行任何异步代码,那么您的后台任务需要使用延迟。看起来您创建了延迟实例,但没有从IBackgroundTaskInstance 获得延迟。所以你可能需要先得到延期。

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

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

    【讨论】:

    • 感谢您的回复。我尝试了你的建议并取得了一些进展。如果我在屏幕一直打开的情况下让设备处于充电状态,则周期性计时器正在运行。但是,如果我锁定屏幕并拔下电源,周期性计时器不会运行。
    • @c2tarun - 您可以通过应用程序转到设置、系统、电池、电池,并将您的应用程序更改为“始终运行”。不理想,但如果这是问题,它可能会给你一个指示。
    • 感谢您的回复,我从这个文档中将我的应用程序变成了 LockScreen 应用程序:msdn.microsoft.com/en-us/library/windows/apps/… 我认为这解决了锁屏时后台任务无法运行的问题。但奇怪的是当任务运行时,它无法进行网络调用。我认为这可能与stackoverflow.com/questions/39133667/… 有关
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      相关资源
      最近更新 更多