原文:UWP -- Background Task 深入解析

1. 重点

锁屏问题

从 Windows 10 开始,用户无须再将你的应用添加到锁屏界面,即可利用后台任务,通用 Windows 应用必须在注册任何后台触发器类型之前调用 RequestAccessAsync:

await BackgroundExecutionManager.RequestAccessAsync();

资源限制

由于对于内存较低的设备的资源约束,后台任务可能具有内存限制,该限制决定了后台任务可以使用的内存上限

在内存受限的设备上,对于可以安装在一台设备上并在任何给定时间使用后台任务的应用数量有所限制。 如果超出该数量,将无法调用注册所有后台任务时所需的 RequestAccessAsync

如果后台任务尝试执行超过此限制的操作,则该操作将失败,并可能生成内存不足的异常情况,但该任务可以处理此情况如果该任务无法处理内存不足的异常情况,或者由于尝试的操作的性质导致无法生成内存不足的异常情况,任务将立即终止

你可以使用 MemoryManager PAI 查询当前内存使用量和限制,以发现上限(若有),并监视正在进行的后台任务内存使用量

进程内后台任务 entry-point

对于进程内后台活动,不要设置 TaskEntryPoint.。将其保留为空可启用默认入口点,这是 Application 对象上称为 OnBackgroundActivated() 的一种新的受保护方法

节电模式

除非你豁免你的应用,以便它可以在节电模式打开时仍可以运行后台任务和接收推送通知,否则当节电模式功能启用时,如果设备未连接到外部电源且电量低于指定剩余电量,它将阻止后台任务运行。 这不会阻止你注册后台任务

时间限制

后台任务受其基于触发器类型获取的时钟时间使用的限制。

大多数触发器限制为 30 秒的时钟时间使用,如果后台活动的运行时间超过执行时间限制,即使在应用的前台进程内运行,后台活动也会终止(进程内后台任务)。而另一些触发器在完成耗时任务时最多可以运行 10 分钟。 为了延长电池使用时间并为前台应用提供最佳用户体验,后台任务应该是轻量级任务

2. 概述

Reason: Windows Store apps have their threads suspended when not in the forground.

Benefit: This prevents background apps fom consuming battery power and prevents apps the user is not interacting with from affecting the responsiveness of the foreground app.

  • System can update your tile or show a toast notification even when your app is suspended or terminated. —- Toast and Notification

  • Your app could transfer large files even when in the background. — Networking

All using background task. Windows Store apps can execute code when not in the foreground by using background task.

Background Task architecture

  1. Implement the code you want executed as a background task.

  2. Decide what triggers your background task code (eg: timer , user log in , ..)

  3. Add a manifest declaration so that Windows knows how to active background task code.

    只是决定什么情况下触发,从而运行

  4. Register your app’s background tasks with Windows the first time your app is activated.

注意:

第一次需要在代码中注册

此外,需要在项目中添加对 WinRT 的引用,reference

Background task 启动过程

When a trigger occurs, Windows creates a new process, loads your background task code into it, and calls an entry point. The background task process runs in the package’s app container. (background task typically execute in a different process than the app’s process)

注:Windows Store apps runs in a different security context than a desktop apps. The security context is called app container, and it restricts which resources a Windows Store app can access.

a new process —- 独立进程 (backgroundtaskhost.exe)

需要说明,一般background task 运行在哪个进程,由manifest – declarations – background task – Executable 决定,文档上:

For most of the triggers, you must leave this blank, Which tells Windows to use its own BackgroundTaskHost.exe process.(系统的BackgroundTaskHost.exe, 任务管理器只看见一个)

Background is not allowed to update the app’s user interface, but can update tiles and badges, or cause the display of a toast notification

重点:

The background task process runs in the package’s app container. This means that the manifest’s package capabilities and app declarations do apply to the background task process. The background task process can write to the package’s data setting and folders. (for an app and its background tasks to communicate with each other). One process can signal when data is ready by calling ApplicationData’s SingalDataChanged method.

Your app must run at least once in order to register a background task and its desired trigger with Windows.(第一次在代码中注册)

Once registered, your app can be running, suspended, or even terminated. When the trigger occurs, Windows starts your app’s background task.

//在注册前运行即可
await Windows.ApplicationModel.Background.BackgroundExecutionManager.RequestAccessAsync();

Background task is the only way to execute code when a PC is in Connected Standby mode.

3. 使用后台任务支持应用

3.1 在后台播放媒体

3.2 进程内后台任务和进程外后台任务

有两种方法可以实现后台任务:

  • 进程内

    • 应用及其后台进程在同一进程中运行;
  • 进程外
    • 应用及其后台进程分别在单独的进程中运行。 进程内后台支持在 Windows 10 版本 1607 中引入,目的是简化编写后台任务。 但仍可以编写进程外后台任务

进程外后台任务实现为操作系统在独立进程 (backgroundtaskhost.exe) 中运行的轻型类。 进程外后台任务编写来实现 IBackgroundTask 接口的类。 通过使用 BackgroundTaskBuilder 类注册后台任务。 注册后台任务时,类名称将用于指定入口点

4. 后台任务指南

内外进程中的任务

CPU 配额

后台任务受其基于触发器类型获取的时钟时间使用的限制。 大多数触发器限制为 30 秒的时钟时间使用,而另一些触发器在完成耗时任务时最多可以运行 10 分钟。 为了延长电池使用时间并为前台应用提供最佳用户体验,后台任务应该是轻量级任务。

使用 BackgroundTaskDeferral

如果后台任务类运行异步代码,则确保使用延迟。 否则,当使用 Run 方法(或针对进程内后台任务使用 OnBackgroundActivated 方法)时,你的后台任务可能会提前终止

BackgroundTaskDeferral _deferral; // Note: defined at class scope so we can mark it complete inside the OnCancel() callback if we choose to support cancellation
public async void Run(IBackgroundTaskInstance taskInstance)
{
_deferral = taskInstance.GetDeferral()
//
// TODO: Insert code to start one or more asynchronous methods using the
// await keyword, for example:
//
// await ExampleMethodAsync();
// _deferral.Complete();
}

准备应用更新

如果你的应用将更新,请创建和注册一个 ServicingComplete 后台任务,以便取消注册适用于前一版本应用的后台任务,并注册适用于新版本应用的后台任务。 此时也非常适合在前台运行的上下文之外执行所需的应用更新

建议每个 app 都可以装一个,它可以在 你没运行之前做一些操作

5. 1.Implement your Background Task’s code

 namespace MyApp.BackgroundTasks
{ // NOTE: determines filename "MyApp.BackgroundTasks.WinMD"
using Windows.ApplicationModel.Background; // For IBackgroundTask & IBackgroundTaskInstance
using Windows.Storage; // NOTE: WinRT components MUST be public and sealed
public sealed class MyBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{ // Register cancelation handler (see the "Background task cancellation" section)
// NOTE: Once canceled, a task has 5 seconds to complete or the process is killed
taskInstance.Canceled += (IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) =>
{
// TODO: Tell task it should cancel itself as soon as possible...
}; // Recommended: Adjust task behavior based on CPU and network availability
// For example: A mail app could download mail for all folders when cost is
// low and only download mail for the Inbox folder when cost is high
switch (BackgroundWorkCost.CurrentBackgroundWorkCost)
{
case BackgroundWorkCostValue.Low: // The task can use CPU & network
case BackgroundWorkCostValue.Medium: // The task can use some CPU & network
case BackgroundWorkCostValue.High: // The task should avoid using CPU & network
// This example records the last trigger time in an application data setting
// so the app can read it later if it chooses. We do regardless of work cost.
ApplicationData.Current.LocalSettings.Values["LastTriggerTime"] = DateTimeOffset.Now;
break;
}
}
}
}

Must implemented as a WinRT comment in VS. This project simply creates a dynamic-link library file. The file extension is .WinMD instead of .DLL .

When you register the full name of this class. The windows will be ready to execute this task ,it will try to load a .WinMD file whose name matches the namespace.

加载这文件时候,会先加载构造函数,不写系统默认一个空构造,你写了就不去加载这个空的构造函数。(包含run)

6. Decide what triggers your Background Task’s code

注册要运行的后台任务

通过在 BackgroundTaskRegistration.AllTasks 属性中迭代,查明后台任务是否已注册。 此步骤非常重要;如果应用不检查现有后台任务注册,则它可能会轻松多次注册该任务,这会导致性能问题和工作结束前超出任务的最大可用 CPU 时间

    var taskRegistered = false;
var exampleTaskName = "ExampleBackgroundTask"; foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}

如果后台任务尚未注册,则使用 BackgroundTaskBuilder 创建你的后台任务的一个实例。 任务入口点应为命名空间为前缀的后台任务的名称。

后台任务触发器控制后台任务何时运行。 有关可能的触发器的列表,请参阅 SystemTrigger。

例如,此代码创建一个新后台任务并将其设置为在 TimeZoneChanged 触发器引发时运行:

var builder = new BackgroundTaskBuilder();

builder.Name = exampleTaskName;
builder.TaskEntryPoint = "RuntimeComponent1.ExampleBackgroundTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));

(可选)在触发器事件发生后,你可以添加条件控制任务何时运行。 例如,如果你不希望在用户存在前运行任务,请使用条件 UserPresent。 有关可能条件的列表,请参阅 SystemConditionType

builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));

通过在 BackgroundTaskBuilder 对象上调用 Register 方法来注册后台任务。 存储 BackgroundTaskRegistration 结果,以便可以在下一步中使用该结果

BackgroundTaskRegistration task = builder.Register();

通用 Windows 应用必须在注册任何后台触发器类型之前调用 RequestAccessAsync:

await BackgroundExecutionManager.RequestAccessAsync();

使用事件处理程序处理后台任务完成

你应该使用 BackgroundTaskCompletedEventHandler 注册一个方法,以便应用可以从后台任务中获取结果。 当启动或恢复应用时,如果自从上次在应用前台运行后后台任务就已完成,将调用标记方法。 (如果应用当前位于前台时后台任务完成,将立即调用 OnCompleted 方法

private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args)
{
var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
var key = task.TaskId.ToString();
var message = settings.Values[key].ToString();
UpdateUI(message);
}

回到已注册后台任务的位置。 在该代码行之后,添加一个新的 BackgroundTaskCompletedEventHandler 对象。 提供 OnCompleted 方法作为 BackgroundTaskCompletedEventHandler 构造函数的参数:

task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);

在应用清单中声明你的应用使用后台任务

略^^

具体 Trigger 及其中区别

7. Add manifest declaration

The meaning of Executable field, this tells Windows which process to execute when the trigger fires. (!!!)

This process will load your WinRT component’s .WinMD file and execute your task’s code. There are two options for this field. For most of the triggers, you must leave this field blank, which tells Windows to use its own Background TaskHost.exe process. (Windows or App container?)

注释:Windows Store apps run in a different security context than desktop apps. This security context is called an app container (discussed in the appendix, “App containers”), and it restricts which resources a Windows Store app can access.

For a PushNotificationTrigger, you can leave this field blank or you can specify(指定) the name of your own app’s executable. If you use the latter, Windows will have your app’s process load the WinRT component and run the task in the same process as your app.

This is not the recommended thing to do, but it allows your background task’s code the ability to access the same state (memory) as your app. However, if your app is suspended, all threads but the thread running the background task code remain suspended, so you must not perform any interthread communication or deadlocks will occur. In addition, because the GUI thread remains suspended, the background task cannot update the app’s user interface. If the app’s process is not running, Windows will activate it, but the app is not launched with a main view or hosted view activation. The result of all this is that your background task cannot have any expectations of the app’s state and, in fact, the app might not have its state fully initialized.

For a ControlChannelTrigger, you must not leave the Executable field blank; instead, you must specify your app’s executable name and your WinRT component’s .WinMD file must load in the app’s process.

As mentioned previously, the ControlChannelTrigger is used for RTC apps, and these apps typically have a socket open in the background task. For the app to respond to the incoming call on the socket, the background task and the app have to share the same process. Everything I said earlier still holds true in this scenario too; that is, the app will not be fully initialized and you should avoid interthread communication.

For the declaration’s Entry Point field, enter the full name (including the namespace) of the WinRT class you created in step 1 (for example, MyApp.BackgroundTasks.MyBackgroundTask). This tells the host process the name of the .WinMD file to load (MyApp.BackgroundTasks.WinMD) and the name of the class to construct in order to call its Run method.

Lock-Screen allowing that app’s background tasks to consume system resources even when the PC is on battery power. These apps typically have a real-time networking requirement like a chat or VoIP application

最多显示七个,可以自己去系统里面设置(你的app得支持lock-screen 才行)

8.

UWP -- Background Task 深入解析的更多相关文章

  1. 与众不同 windows phone (13) - Background Task(后台任务)之后台文件传输(上传和下载)

    原文:与众不同 windows phone (13) - Background Task(后台任务)之后台文件传输(上传和下载) [索引页][源码下载] 与众不同 windows phone (13) ...

  2. 与众不同 windows phone (12) - Background Task(后台任务)之 PeriodicTask(周期任务)和 ResourceIntensiveTask(资源密集型任务)

    原文:与众不同 windows phone (12) - Background Task(后台任务)之 PeriodicTask(周期任务)和 ResourceIntensiveTask(资源密集型任 ...

  3. 与众不同 windows phone (11) - Background Task(后台任务)之警报(Alarm)和提醒(Reminder)

    原文:与众不同 windows phone (11) - Background Task(后台任务)之警报(Alarm)和提醒(Reminder) [索引页][源码下载] 与众不同 windows p ...

  4. Spring源码情操陶冶#task:scheduled-tasks解析器

    承接前文Spring源码情操陶冶#task:executor解析器,在前文基础上解析我们常用的spring中的定时任务的节点配置.备注:此文建立在spring的4.2.3.RELEASE版本 附例 S ...

  5. running a background task over ssh

    原文: Why does running a background task over ssh fail if a pseudo-tty is allocated? 问题: I've recently ...

  6. (转载)activity外部调用startActivity的new task异常解析

    activity外部调用startActivity的new task异常解析 泡在网上的日子 / 文 发表于2013-09-07 12:45  第1314次阅读 异常,android,activity ...

  7. Spring源码情操陶冶#task:executor解析器

    承接Spring源码情操陶冶-自定义节点的解析.线程池是jdk的一个很重要的概念,在很多的场景都会应用到,多用于处理多任务的并发处理,此处借由spring整合jdk的cocurrent包的方式来进行深 ...

  8. UWP Background过渡动画

    首先说两件事: 1.大爆炸我还记着呢,先欠着吧... 2.博客搬家啦,新地址:https://blog.ultrabluefire.cn/ ==========下面是正文========== 前些日子 ...

  9. ios background task

    今天要实现一个需求,当用户触摸HOME键,将应用切换到后台时,启动自动备份的任务.这涉及到ios的后台任务处理,本文简单总结一下 首先,ios app有5种状态,分别是:not running, in ...

随机推荐

  1. [Django] Start a new django project

    Assume we already have a env created call 'demo-env': cd demo-env . bin/activate pip install django ...

  2. CF439E:The Untended Antiquity - 哈希 + 二维树状数组

    Magic Door 题目大意 有一个n*m的网格,支持三中操作: 1.在x1,y1,x2,y2为顶点的矩形周围围上栅栏 2.将x1,y1,x2,y2为顶点的矩形周围的栅栏拆掉 3.询问x1,y1,x ...

  3. Java冒泡排序与直接选择排序代码随笔

    冒泡排序:延申的有很多种,有的是先确定最大值放到后面,有的是先确定最小值放到前边,还有就是反过来,先确定最小值的位置,但是本质都是:不断两两比较,交换位置...第一趟确定一个最大(最小)值放到前边(后 ...

  4. 【项目积累】对JSON数据的处理

    [项目简述]         接触.NET项目非常长一段时间了,前台用的都是MVC框架.不知道大家是否想过一个问题.我们是怎样将数据显示到前台的,换句话说,MVC能够识别怎么样的数据形式?答案非常ea ...

  5. Android Studio中创建java项目

    1.创建普通的android工程 2.创建一个module 3.module类型选择java library 4.填写libary和class的名字 5.生成的工程如图所示 6.然后点击Run --- ...

  6. android仿新浪引导界面

    最近在研究如何做出仿微信,仿新浪等应用,第一次安装使用的使用展示应用程序的新特性和用法. 实现功能:左右手势滑屏 底部小圆点随当前显示页跳动 浮动按钮显示.当触屏事件发生显示,否则就渐渐消失 先转个文 ...

  7. 在CSDN博客中添加量子恒道统计功能的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 什么是量子恒道统计?量子恒道统计是一套免费的网站流量统计分析系统.致力于为所有个人站长.个人博主.所有网站管理者.第三 ...

  8. GammaRay is a tool to poke around in a Qt-application(确实很多功能)

    GammaRay is a tool to poke around in a Qt-application and also to manipulate the application to some ...

  9. docker入门0:常识知识扫盲

    Docker 是一个开源项目,基于 Go 语言实现,是一套轻量级的操作系统虚拟化解决方案.用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单. Docker通常用于如下场景: web ...

  10. Android二维码功能实现

    最近二维码真是越来越火了,随便电视上.网络上.商场里,到处都是二维码.而内嵌二维码扫描功能的软件也越来越多,QQ.微信.UC浏览器等等应用都可以对着二维码扫一扫,感觉我们自己的应用里不加上二维码扫描功 ...