在WP7.1中针对Background Agent的新API增加了蛮多非常强大的部分,以下将介绍Scheduled Multi Tasking的部分。
Scheduled Multi Tasking主要是让Application支援多工模式来执行任务,让Application不在前景模式下也可以继续在背景执行某些特定的任务,例如:背景下载、背景更新资料、背景唿叫服务…等。
然而,WP7.1提供Agent的模式,让开发Application时将要背景执行的逻辑,独立放置于Agent之中透过排程来完成任务。
但要注意的是,Agent与Application必竟还是属于不同的专案,因为IsolatedStorage中的IsolatedStorageSettings无法共用,要交换资料需透过IsolatedStorage档案或其他方式来交换。
因此,在设计一个支援Background Agent(ScheduledTaskAgent)的Application时,我个人会有几个考量:
1. 将背景执行的逻辑独立成一个类别或模组,由该模组完成所有背景的任务;
2. 使用设定档(config)的方式,将参数或执行结果独立于档案,提供Application与Agent均可以取得;
3. Agent是背景的任务,在背景发生Exception的容错机制需要特别设计,尽量透过通知告知用户;
接下来,将细部去讨论Scueduled Tasking由那些重要的元素组成:
〉Microsoft.Phone.Scheduler - Scheduled Multi Tasking:
WP7.1允许Schedule Task与Background Agent在背景执行它们的任务,然而Schedule Task与Background Agent使用上却有所不同:
‧Schedule Task:重点在于指定「週期性/延迟性」执行任务,透过设定Schedule的时间频率重覆地去执行任务;
‧Background Agent:根据不同的Agent可在细分使用重点,但较属性一次性任务或接收外部事件所触发的任务;
在Microsoft.Phone.Scheculer针对Scheulde提供了Task与Notification的使用,其用法上Schedule Task又是另一种用途,针对Schedule Notification会在另一篇<>进行说明。
然而,在Scheulde Task的使用上有几个重要元系一定要去了解的,以下将详细说明:
A. ScheduledActionService:
专用于管理该设备所有的Scheduled Actions。Scheduled Actions包括了可用于通知的Alarm、Reminder,更包括下方介绍的二个运行于Background Agent的Periodic Task与Resource-Intensive Task。其重要的方法如下:
名称 | 说明 |
Add | 向作业系统註册一个Scheduled Action。主要透过Scheduled Action的Name做为识别值。 |
Find | 透过特定的Name找出Scheduled Action。 |
GetActions(Of T) | 回传系统中所有特定类型的Scheduled Actions。 |
LaunchForTest | 指定特定的延迟时间与ScheduledTask后,要求Background Agent执行该ScheduledTask。 |
Remove | 从Scheduled Action Service将指定的名称的Scheduled Action移除。 |
Replace | 通常会配合Find找出指定Name的Scheduled Action,并加以取代它。 |
B. PeriodicTask:
Periodic(定期) Task是一种定期代理运作的观念,专门针对运作背景任务所需时间较少,而且是执行隔间具有规律週期性的情境。
常见的使用情境,例如:定期上传手机的Location资讯、完成少量资料的同步、更新Tile状态…等。
B-1. 使用Periodic Task的约束与时间週期建议
约束/建议 | 说明 |
排程时间间隔:30分 | 通常每30分执行一次,在电力状况不错的情形下可以配合其他background process使用时,也可以设定接近上下差距10秒的使用。 |
排程持续时间 | 通常支援持续执行25秒,但也可能因为其他塬因造成该agent被提早结束。 |
电池为节约模式时,能防止Exception | 由于电池是否要使用节约模式是由用户自行选择。如果该模式被选择时,当电池进入节约模式时,periodic task将有可能无法使用。 |
每一个设备在Periodic Task的限制 | 为了让电池最大化使用,不同的设备对电池的使用有一定的控制範围,因此,可能限制一个设备最多有几个Agent可以被执行,如果超过,它会自动被turn off。 |
C. ResourceIntensiveTask:
Resource-Intensive(资源密集) Task是针对需要相对较长的处理时间,或是遇到需使用大量手机电源、网路等资源时较为适用的类型。
常见的使用情境,例如:同步大量的资料(如App需要下载大量的资料至手机端才能让App运行)…等。
C-1. 使用ResourceIntensiveTask的约束与时间週期建议
约束/建议 | 说明 |
持续时间:10分鐘 | 通常resource-intensive agent一般执行持续约10分鐘,如果有其他如下方的限制,将会提早停止agent的执行。 |
外部电力需求 | 除非设备已连接外部的电力来源,否则无法执行。 |
无行动网路能线能力 | 除非设备已通过Wi-Fi、行动网路或连接到PC,否则无法执行。 |
最小电力需求 | 除非电力超过90%的情形,否则无法执行resource-intensive agent。 |
设备萤幕被锁定状态 | 除非电话处于锁定的状态,否则无法执行resource-intensive agent。 |
通话中无法使用 | 当手机处于通中状态时,resource-intensive agent无法使用。 |
不能改变网路状态为行动网路 | 如果resource-intensive agent企图去唿叫AssociateToNetworkInterface(Socket, NetworkInterfaceInfo)来指定任何一种行动网路(GSM或CDMA),则会失败。 |
这二个元素其实都是由ScheduleAction与ScheduledTask抽象类别实作出来的,它们分别有自身使用的情境与适用性,
二者最大的差别即在于使用情境与需要耗用手机资源的多少,以及resource-intensive task要在萤幕锁定与电力90%以上才能执行。
由于使用resource-intensive task要求的限制实在很多,因此,在设计Scheduled Task时需要特别考虑这个部分,至于其他相关的
属性就大同小异了,以下简介其较长使用到的属性:
名称 | 说明 |
Description | 设定/取得有关该Scheduled Task的描述。该描述的内容将会出现于手机「Settings/Applications/Background Tasks Settings」的画面中。 如下图:以Background Scheulde为程式名称:
![0001 0001](http://www.silverlightchina.net/uploads/allimg/111127/19432I593-1.png) |
ExpirationTime | 设定/取得Scheduled Task到期的时间。 |
IsScheduled | 取得Scheduled Task状态是否为启动。 |
LastExitReason | 取得Agent执行最近一次Task被结束的理由。 |
LastScheduledTime | 取得Agent执行最近一次Task的时间,以手机时间为主。 |
Name | 取得Scheduled Action的名称。 |
了解了二个元素的基本属性与使用情境后,有几个使用Background Agent要特别注意的:
1. 一个Application只能有一个Background agent(ScheduledTaskAgent),但Agent可以单独使用PeriodicTask、ResourceIntensiveTask
或者二个同时使用。要注意的是一个Agent只能有一个PeriodicTask与一个ResourceIntensiveTask。
2. Background Agent(ScheduledTaskAgent):
2-1. 透过OnInvoke(ScheduleTask)触发Agent逻辑的部分;
2-2. 已成功执行完所有任务时,记得唿叫NotifyComplete()告知Agent已完成任务;
2-3. 如果在执行过程发生错误或是无法执行Task时,要记得唿叫Abort()告知Agent接下来取消运作,然而即可以在Application端取得
ScheduledTask中的IsScheduled属性为false。但要注意的是如何Abort()之后,要记得使用ShellToast告知用户,以免用户不知道。
3. Background Agent在记忆体使用量的控制:
3-1. Periodic agents与resource-intensive agents允许在每次执行Task时,不超过6MB记忆体用量。
3-2. Audio agents则限制不能超过15MB记忆体用量。
3-3. 在Debug模式下则不限制,但可以透过API去查询在每一个部分使用记体忆的状况。
4. 预设Agent为二个星期后需要重新安排Scheduled:
虽然可以透过ScheduledTask中的LastScheduledTime去确认究竟最近一次执行的Datetime为何,并且使用ExpirationTime去指定Task
可运行的时间长度。但是使用ScheduledTask可能因为条件限制(例如遇到执行Task时没网路能力,自动要求Agent延后执行),造成Task
长时间没有被执行,为了确保Task不会一直占住不使用,透过设定2个星期可存活时间,可以自动解决这个问题。设定ExpirationTime可
在每一次执行Application于前景状况时,进行判断与设定。
5. Scheduled Agent在连续二个Crash后自动取消:
由于使用Periodic agents与resource-intensive agetns是交由Agent去控制,因此,当Agent连续出现二次以上的Crash或无法预期的错误,
该Agent将会被停止,需透过Application回到前景模式再重新启动它。