【问题标题】:Background task spontaneous completion C#后台任务自发完成C#
【发布时间】:2015-06-09 10:22:06
【问题描述】:

注册一个后台任务:

    string myTaskName = "Task";

   foreach (var cur in BackgroundTaskRegistration.AllTasks)
        if (cur.Value.Name == myTaskName)
        {
           return;
        }

   await BackgroundExecutionManager.RequestAccessAsync();

   BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder 
   { 
        Name = "Task", 
        TaskEntryPoint = "Background.Task"
   };
   taskBuilder.SetTrigger(new TimeTrigger(15, true));
   BackgroundTaskRegistration myFirstTask = taskBuilder.Register();

后台任务在 Windows 运行时组件中创建为一个单独的类:

public sealed class Task : IBackgroundTask 
        {
            public async void Run(IBackgroundTaskInstance taskInstance)
            {
                BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

//logic, send http get request, connect to db

                deferral.Complete();
            }
}

到了执行任务的时候——它可能运行随机次数(1-15次)然后自发终止不再启动,要解决这个问题需要重新注册任务。可能是什么原因?

VS 在我想运行任务时显示此错误:

【问题讨论】:

  • 我不知道在 Win 8.0/8.1 上的新应用程序中的情况如何,但在 WinPhones 上,每个任务/作业都有一些运行时限制:max.memory 使用量和 max.memory 使用量。单次运行时间有限。当超过这些措施中的任何一个时,任务/作业将被终止并且其计划被禁用,直到应用程序重新运行并且任务重新从头开始重新计划。在 WinPhone 框架上,限制非常严格,
  • 哦,从任务/作业中冒出的任何未处理的异常也会立即导致其计划被取消。
  • @quetzalcoatl,win 手机 8.1 上的应用程序。这不是因为对记忆的压力。我结束了 toast 通知而不是逻辑 batskground 任务。再次出现错误:C
  • 原因是一个参数异常,您可以在屏幕截图中看到。
  • @Jehof,不,这不是原因。如果后台任务为空 - 我也收到此错误。 Try/catch 无法捕捉到这个错误。我不知道这个错误是如何产生的。

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


【解决方案1】:

在 Windows Phone 上,定期后台任务以至少 30 分钟的间隔执行。

Windows 有一个内置计时器,它每隔 15 分钟运行一次后台任务。 请注意,在 Windows Phone 上,间隔为 30 分钟。

(来源:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977059.aspx?f=255&MSPPError=-2147217396

如果我是你,我会将时间间隔更改为更安全的时间间隔(例如 60 分钟) - 你以后总是可以尝试更小的间隔。并查看oneShot 标志,在您的情况下设置为true。将其设置为 false 以使您的任务运行多次。

您的异常看起来也不健康。您说它甚至发生在后台任务为空的情况下-您应该修复它,以确保安全。

我建议您使用 Visual Studio 中的生命周期功能手动启动和调试您的后台任务几次。也许还有其他事情会导致您的任务终止。

但首先要检查间隔。

【讨论】:

  • 好的,我会试试的。谢谢
  • 解决这个问题:taskBuilder.SetTrigger(new TimeTrigger(15, FALSE)); OneShot 必须为 false,您可以将时间设置为 15 分钟。
  • 既然您已经指出了这一点,我知道我想在答案中添加什么。当我看到你的问题时,我想:“Oneshot 是真的 - 这不可能是正确的”,但在发布我的答案时完全忘记了它:) 我会编辑帖子以反映这一点。