前面提到,
計劃任務允許應用程式執行背景代理程式,執行條件是主程式未啟用。與計劃通知不同的是,計劃任務只能選擇兩種類型執行,即 PeriodicTask 和 ResourceIntensiveTask.
PeriodicTask 定期執行,但是執行時間短,且限制使用處理周期和記憶體等系統資源。此類型適合快速任務,比如檢查啟用位置功能的WEB服務的使用者數,或者緩衝小量資料。
ResourceIntensiveTask 不定期執行,在裝置處於資源充沛的情況下執行,比如裝置處於WIFI網路連接狀態並且裝置採用外接電源供電。此類型的任務在允許使用充足的裝置資源時,可以運行更長的時間處理大量的資料,即此類型的任務執行時間是彈性的。
以下摘自MSDN。,
計劃任務和後台代理都允許應用程式在後台執行代碼,即使當應用程式未在前台運行時也是如此。不同類型的計劃任務是針對不同類型的幕後處理方案設計的,因此具有不同的行為和限制。本主題介紹計劃任務的計劃、期間和限制。
計劃任務的類型
下面是計劃任務的類型。請注意,ScheduledTask 派生自 ScheduledAction。在後台啟動並執行代碼放置在從 ScheduledTaskAgent(派生自 BackgroundAgent)派生的類中。
計劃任務類型 |
說明 |
PeriodicTask |
定期代理以定期重複的間隔運行一小段時間。這種類型的任務的典型方案包括上傳裝置的位置以及執行少量的資料同步。 |
ResourceIntensiveTask |
資源密集型代理在手機符合與處理器活動、電源以及網路連接有關的一組要求時運行,啟動並執行時間相對較長。這種類型任務的典型方案是,在使用者沒有主動使用手機時將大量資料同步到手機。 |
後台代理生命週期
一個應用程式可能只有一個後台代理。可以將該代理註冊為 PeriodicTask、ResourceIntensiveTask 或兩者。運行代理的計劃取決於註冊的任務類型。將在本主題的後面部分介紹計劃的詳細資料。一次只能運行代理的一個執行個體。
代理的代碼由應用程式在從 BackgroundAgent 繼承的類中實現。代理啟動時,作業系統調用 OnInvoke(ScheduledTask)。在該方法中,應用程式可以確定它以哪種 ScheduledTask 類型運行,並執行相應的操作。代理完成其任務之後,它應該調用 NotifyComplete()()()() 或 Abort()()()() 以讓作業系統知道它已完成。如果任務成功,則應該使用 NotifyComplete。如果代理無法執行其任務(如所需的伺服器不可用),則代理應該調用 Abort,這將導致 IsScheduled 屬性設定為 false。前台應用程式可以在其運行時檢查該屬性,以確定是否調用了 Abort。
所有計劃任務類型的限制
以下限制適用於所有計劃任務。
限制 |
說明 |
不支援的 API |
有一組無法由任何計劃任務使用的 API。使用這些 API 將導致在運行時引發異常,或者將導致在提交到 Windows Phone 商城 期間應用程式無法認證。有關受限制的 API 的列表,請參閱 Windows Phone 的後台代理不支援的 API。 |
記憶體使用量上限 |
定期代理和資源密集型代碼任何時候都不能使用超過 6 MB 的記憶體。音頻代理限制為 15 MB。如果計劃任務超過此記憶體上限,則立即終止。 在調試器下運行時,暫停記憶體和逾時限制。可以使用 ApplicationMemoryUsageLimit API 查詢前台應用程式和後台代理的記憶體限制。 |
每隔兩周需要重新計劃 |
使用 ScheduledTask 對象的 ExpirationTime 屬性設定之後不再運行任務的時間。當使用 Add(ScheduledAction) 方法計劃操作時,該值必須設定為兩周之內的某個時間。當與該任務相關 App程式在前台運行時,可能會重新計劃該任務並將到期時間重設為從目前時間起最多兩周。 |
兩次連續崩潰之後取消代理計劃 |
如果由於超過記憶體配額或任何其他未處理的異常而連續兩次退出,則取消定期代理和資源密集型代理的計劃。代理必須由前台應用程式重新計劃。 |
定期代理的限制
以下是定期代理的計劃、期間和常規限制。
限制 |
說明 |
計劃間隔:30 分鐘 |
定期代理通常每隔 30 分鐘運行一次。若要最佳化電池使用時間,定期代理的運行可以與其他後台進程一致,因此執行時間可能最多漂移 10 分鐘。 |
計劃期間:25 秒 |
定期代理通常運行 25 秒。其他限制可能會導致代理提取終止。 |
省電模式可能會阻止執行 |
省電模式是一個選項,使用者可以在裝置上啟用該選項以指示應該優先考慮電池使用時間。如果啟用此模式,則定期代理可能不運行,即使間隔已過也是如此。 |
每個裝置的定期代理限制 |
為了協助最大程度地提高裝置的電池使用時間,對手機上可以計劃的定期代理數量進行了硬性限制。它因每個裝置配置而異並且可以低到 6。還有另一個低於硬性限制的限制,超過該限制之後會警告使用者他們正在運行多個後台代理,因此電池消耗可能比較快。 警告:當超出裝置限制時,如果您嘗試添加定期後台代理,則對 Add(ScheduledAction) 的調用將引發 InvalidOperationException。由於每個裝置的定期代理限制非常低,因此您的應用程式很可能會遇到此異常。出於此原因,您在添加定期代理時捕獲此異常非常重要,這樣您的應用程式就不會崩潰。其範例程式碼可以在 Windows Phone 的後台代理最佳做法中找到。 |
資源密集型代理的限制
以下是資源密集型代理的計劃、期間和常規限制。
限制 |
說明 |
期間:10 分鐘 |
資源密集型代理通常運行 10 分鐘。其他限制可能會導致代理提取終止。 |
需要外部電源 |
除非裝置串連到外部電源,否則不運行資源密集型代理。 |
需要非行動電話通訊串連 |
除非裝置通過 Wi-Fi 或 PC 串連建立網路連接,否則資源密集型代理不運行。 |
最低電池電量 |
除非裝置的電池電量高於 90%,否則資源密集型代理不運行。 |
需要裝置螢幕鎖定 |
除非裝置螢幕鎖定,否則資源密集型代理不運行。 |
非活動手機呼叫 |
當手機呼叫處於活動狀態時,資源密集型代理不運行。 |
不能將網路更改為行動電話通訊 |
如果資源密集型代理嘗試調用指定 MobileBroadbandGSM()()()() 或 MobileBroadbandCDMA()()()() 的 AssociateToNetworkInterface(Socket, NetworkInterfaceInfo),則該方法調用失敗。 |
如果裝置達到了一種狀態,即,符合所有需要的條件並且啟動了資源密集型代理,那麼當裝置狀態發生更改以至於不符合任何條件時,則會立即終止資源密集型代理。
------------------------------------------------------------------------------------------------------
在Wondwos Phone 7.1中,提供了可以進行多個工作計劃任務的方法,我們可以定義一個工作內容之後,交由作業系統來執行這段程式,不過因為手機本身的資源限制,所以並不是所有的工作都可以執行。Windows Phone 7.1中支援二種可以在背景計劃任務執行的工作:
1、PeriodicTask
2、ResourceIntensiveTask
這二種工作執行的方式都有要求的條件:
PeriodicTask:
執行時間:每30分鐘執行一次,誤差可能約10分鐘
記憶體最大使用量:小於6 MB
可執行時間:25秒。
省電模式時可能不執行
可執行上限數:6個。
ResourceIntensiveTask:
記憶體最大使用量:小於6 MB
可執行時間:10分鐘。
執行條件:外接電源、需使用Wi-Fi或是直接連接電腦、電池電源需大於90%、營幕不可鎖定、不在接電話的狀態等。
每個應用程式最多隻能設定一個PeriodicTask 和 ResourceIntensiveTask,工作的到期日(ExpirationTime)必需在二周內,而且有部份API無法使用,要排定工作必須在使用者第一次執行的應用程式的時候,沒辦法在安裝時就啟動排程,使用上的限制還蠻多的。
樣本一:
建立計劃任務的方式還蠻簡單的,先建立一個基本的Windows Phone App,再建立計劃任務的項目,App引用計劃任務。
。
接下來就是在App放一個button來啟動工作排程啦:
private void btnStart_Click(object sender, RoutedEventArgs e) { PeriodicTask task = (PeriodicTask)ScheduledActionService.Find("TaskAgent"); if (task == null) { task = new PeriodicTask("TaskAgent"); task.Description = "顯示目前時間"; } else { //沒在排程狀態 if (!task.IsScheduled) { string lastResult; if (IsolatedStorageSettings.ApplicationSettings.TryGetValue<string>("taskResult", out lastResult)) { if (lastResult == "Succes") { MessageBox.Show("使用者已關閉排程"); ScheduledActionService.Remove(task.Name); return; } else if (lastResult == "Faillure") { } } } ScheduledActionService.Remove(task.Name); } //到期時間 task.ExpirationTime = DateTime.Now.AddDays(14); try { ScheduledActionService.Add(task); #if DEBUG_AGENT ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(60)); #endif } catch (InvalidOperationException) { MessageBox.Show("排程執行已達上限數或使用者停止相關功能。"); } catch (SchedulerServiceException sse) { MessageBox.Show(sse.Message); } }
把工作加入排程之前,記得先判斷是否有重覆;如果已經有排程了,那就要判斷目前排程執行的狀況,若是需要重新排程,就把目前的排程先移除之後再重新加入。
另外,測試時可以利用ScheduledActionService.LaunchForTest來達到快速執行(不然最少都要等30分鐘左右哦!)
protected override void OnInvoke(ScheduledTask task)
{
if (task is PeriodicTask)
{
// Logic for Periodic Task
}
else
{
// Logic for ResourceIntensiveTask
}
// Use this to invoke your task much quicker when debugging
#if DEBUG_AGENT
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(60));
#endif
// Tell the Scheduler we are done
NotifyComplete();
}