【Win 10 應用開發】在App所在的進程中執行后台任務


在以往版本中,后台任務都是以獨立的專用進程來運行,因此,定義后台任務代碼的類型都要位於 Windows 運行時組件項目中。

不過,在14393中,SDK 作了相應的擴展,不僅支持以前的獨立進程中運行后台任務,也允許后台任務與應用程序位於同一個進程中執行,即單進程后台任務(Single – Process)。

聽起來很高深?其實很Easy,和以往的多進程模式的后台任務差不多,只是有以下兩點不同:

  1. 對於獨立進程的后台任務,實現方法是實現 IBackgroundTask 接口,然后實現 Run 方法;而如果你希望讓后台任務在應用所在的進程中執行,可以重寫 Application 類的 OnBackgroundActivated 方法就可以了,它類似於 IBackgroundTask 的 Run 方法。在OnBackgroundActivated方法中,你可以通過方法參數獲得一個IBackgroundTaskInstance實例,所以與Run方法的處理是一樣的。
  2. 在配置清單文件時,獨立進程中執行的后台任務是必須指明入口點的,即后台任務類的類型名,包含命名空間路徑。而如果后台任務是在應用進程中執行的話,就不需要指點入口點,因為后台任務的入口點與應用相同,就是App類。

 

只要明白了以上兩點,你就明白了95%了,剩下的5%,就等老周來演示給大伙瞧吧。

App Service 的實現跟后台任務差不多,本次表演,老周就選用AppService來試水吧。

這個示例只有小學二年級水平,它分為兩個應用,一個應用具備app service,另一個應用調用它。service的功能是計算兩個整數的乘積,所以說是小學二年級水平。

先看app service的應用實現,項目模板會為我們生成一個App類,基類是Application,很簡單,直接重寫OnBackgroundActivated方法就行了。

 

 protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args) { …… }

 

這個方法就相當於Run方法,所以,和以前一樣,在其中添加處理代碼。

            IBackgroundTaskInstance taskInstance = args.TaskInstance; var taskDef = taskInstance.GetDeferral(); taskInstance.Canceled += (ca, cb) => taskDef.Complete(); if (taskInstance.TriggerDetails != null && taskInstance.TriggerDetails is AppServiceTriggerDetails) { AppServiceTriggerDetails details = taskInstance.TriggerDetails as AppServiceTriggerDetails; string appsvName = details.Name; if (appsvName == "my.multip") { AppServiceConnection conn = details.AppServiceConnection; conn.RequestReceived += async (r1, r2) => { var svdef = r2.GetDeferral(); var request = r2.Request; ValueSet inputs = request.Message; int x = Convert.ToInt32(inputs["a"]); int y = Convert.ToInt32(inputs["b"]); int o = x * y; ValueSet sendBack = new ValueSet(); sendBack["r"] = o; await request.SendResponseAsync(sendBack); svdef.Complete(); taskDef.Complete(); }; conn.ServiceClosed += (k1, k2) => { Debug.WriteLine("app service連接關閉。"); taskDef.Complete(); }; } }

 

 

然后就完事了,注意在清單文件中,不要指定入口點了。

 <Extensions>
        <uap:Extension Category="windows.appService">
          <uap:AppService Name="my.multip" />
        </uap:Extension>
      </Extensions>

 

 

現在可以在另一個應用中調用了。

            AppServiceConnection conn = new AppServiceConnection(); conn.AppServiceName = "my.multip"; conn.PackageFamilyName = txtPkname.Text; var state = await conn.OpenAsync(); if (state == AppServiceConnectionStatus.Success) { ValueSet input = new ValueSet(); input["a"] = ComputeObject.Num1; input["b"] = ComputeObject.Num2; var response = await conn.SendMessageAsync(input); if (response.Status == AppServiceResponseStatus.Success) { ValueSet res = response.Message; ComputeObject.Result = Convert.ToInt32(res["r"]); } }

 

調用App Service 時,先new一個AppServiceConnection,然后指定包含app service的應用的Package的名字,這個包名可以用以下方法來獲取:

  • 在包含app service的應用中,訪問這個靜態屬性獲取:Windows.ApplicationModel.Package.Current.Id.FamilyName。
  • 用VS生成項目,然后打開【輸出】窗口,顯示來源選擇“生成”,這樣你就能看到包含應用服務的應用包名了。如下圖。

00001

 

不能使用清單文件中的包名,因為那個包名不完整。不過,你得注意了,通過【輸出】窗口獲取包名的時候,包的名字中要去掉版本號和平台描述,比如,我的項目中輸出的生成的包名為:

62da1ba5-7faf-4109-b82a-7a6027dbc3a3_1.0.0.0_x86__6pcpwfmxf0rfc

 

其中,1.0.0.0是版本號,要去掉,x86是平台描述,也要干掉,后面的6pcpwfmxf0rfc可能是開發者的標識,不能去掉。最終得到需要的包名為:

62da1ba5-7faf-4109-b82a-7a6027dbc3a3_6pcpwfmxf0rfc

前面的GUID是應用包名字,后面要接一個下划線,然后是6pcpwfmxf0rfc。

 

把這個最終取得的名字賦值給AppServiceConnection的PackageFamilyName屬性即可,AppServiceName屬性表示要調用的app service的名字。

准備好參數后,調用OpenAsync方法打開連接,一定要先打開連接,才能調用應用服務。使用SendMessageAsync方法發送輸入參數,參數是一個ValueSet對象,其實是個字典,可以自定義參數結構。在本例中,既然要計算乘法運算,當然是要傳遞兩個整數值了。

SendMessageAsync方法調用后,會異步返回一個AppServiceResponse實例,該實例中包含着一些從應用服務返回的內容,訪問Message屬性就得到應用服務響應的ValueSet,並可從中取出需要的數據,該例子中,是取出計算結果。

好,項目干完了,咱們來試試,同時運行兩個應用,然后試着調用一下應用服務。

001

 

 

效果已達到, 這時候,大伙可能會疑惑,如果包含app serivce的應用進程退出后,還能調用應用服務嗎?沒事,許多事情就是試出來的,試試看。把包含應用服務的應用進程結束掉,然后再調用一次,發現是可以成功調用的。

有了這一招,定義后台任務就靈活很多了,既可以在獨立進程中完成,也可以在應用進程中完成,具體采用哪一種,就看實際情況了。一切東西都是靈活運用的,千萬不要把技術學死了。那些整天吃飽了撐着,想把什么東西都變成公式化的思想是幼稚的、死板的,這個世界上,不可以量化的事情多得很。

不過,老周可以發表一些低見,僅作參考。如果后台任務的觸發源與應用程序關系不大,比如用戶登錄/注銷時執行的,每隔一段時間執行的(定時),這些情況,建議把后台任務寫到獨立的Windows運行時組件項目中,讓它以獨立的進程進行。

要是后台任務是應用程序主動觸發的,比如后台轉碼(音/視頻處理),或者由應用程序使用Application Trigger觸發的后台任務,都可以考慮把它歸入應用程序進程中,即本文所講述的情況。

 

好了,今天的牛逼吹完了,該去喝點茶了(白開水最好喝,集天地靈氣,無雜質,無負作用),下一篇文章咱們聊聊預啟動的事情。

示例源代碼下載

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM