New Windows 10 SDK - Multi-instance UWP apps

来源:https://www.cnblogs.com/shaomeng/archive/2018/03/22/8620370.html
-Advertisement-
Play Games

概述 前面一篇 About Windows 10 SDK Preview Build 17110 中,我們簡單介紹了 Multi-instance UWP Apps,今天結合開發過程詳細講解一下。 在 Windows 10 Version 1803 以前,UWP App 同一時間只能啟動一個實例,而 ...


概述

前面一篇 About Windows 10 SDK Preview Build 17110 中,我們簡單介紹了 Multi-instance UWP Apps,今天結合開發過程詳細講解一下。

在 Windows 10 Version 1803 以前,UWP App 同一時間只能啟動一個實例,而在 1803 開始,UWP App 可以通過開發者的配置選擇來支持多實例。如果一個多實例 UWP App 正在運行,這時一個激活請求發送過來,平臺不會直接激活當前的實例,而是會創建一個新的實例,運行在單獨的進程中。

開發過程 

配置多實例支持

多實例特性需要在 Visual Studio 中安裝新的項目模板:Multi-Instance App Project Templates.VSIX, 安裝後,使用 C# 和 C++ 都可以創建項目。

兩個模板會被安裝:

  • Multi-Instance UWP app -- 創建一個多實例的 App
  • Multi-Instance Redirection UWP app -- 提供一個附加的邏輯,讓用戶可以選擇啟動新實例,或者選擇目前激活的實例。可以想象一下 Office 打開或編輯文件時的場景。

      

這兩個模板都會在 manifest 文件中添加 SupportsMultipleInstances,其中 desktop4 和 iot2 首碼標誌了項目只支持傳統桌面 Windows 和 IoT 系統。manifest 配置如下,我們只保留了新增的部分:

<Package
  ...
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"  
  IgnorableNamespaces="uap mp desktop4 iot2">
  ...
  <Applications>
    <Application Id="App"
      ...
      desktop4:SupportsMultipleInstances="true"
      iot2:SupportsMultipleInstances="true">
      ...
    </Application>
  </Applications>
   ...
</Package>

實際運行時,每次點擊 App 的磁貼,都會啟動一個新的實例。如下圖中,App 顯示了啟動的時間,在任務欄和運行視窗可以看到,兩個實例同一時間在運行狀態。 

 

多實例激活重定向

UWP App 對多實例的支持,可以讓同一 App 的多個實例可以同時在運行。它運行開發者自己定義,是每次開啟一個新的實例,還是重定向某個目前激活的應用。舉例來說,讓你想使用 App 編輯一個文件,而這個文件正在 App 中被編輯,這時就不應該再開啟一個新的實例,而是應該重定向當前正在編輯文件的實例。這就會用到 Multi-Instance Redirection UWP app 模板。

Multi-Instance Redirection UWP app 模板和我們上面看到的一樣,對 manifest 文件會做同樣的調整。同時該模板會增加一個 Program.cs 文件,在文件中包含一個 Main() 方法,靠這個方法來實現多實例激活的重定向操作。

我們來重點看看 Program.cs 文件中的 Main() 方法

  • activatedArgs 中包含了應用啟動時我們定義的參數,我們根據這些參數,比如 key 來決定多實例的重定向方式;
  • AppInstance.RecommendedInstance 系統推薦的實例,如果有,我們可以重定向到這個實例;
  • 多實例間唯一性的標識 key 的生成方式,我們可以根據 activatedArgs 來自定義,在預設的示例代碼中,採用了隨機數判斷單雙數的方式;
  • FindOrRegisterInstanceForKey(key) 會查詢當前對應 key 的實例,如果沒有則新註冊一個實例;
  • 判斷實例是不是新註冊的,如果是則啟動,如果是查詢到的原有實例,則重定向到那個實例;
static void Main(string[] args)
{
    // First, we'll get our activation event args, which are typically richer
    // than the incoming command-line args. We can use these in our app-defined
    // logic for generating the key for this instance.
    IActivatedEventArgs activatedArgs = AppInstance.GetActivatedEventArgs();

    // In some scenarios, the platform might indicate a recommended instance.
    // If so, we can redirect this activation to that instance instead, if we wish.
    if (AppInstance.RecommendedInstance != null)
    {
        AppInstance.RecommendedInstance.RedirectActivationTo();
    }
    else
    {
        // Define a key for this instance, based on some app-specific logic.
        // If the key is always unique, then the app will never redirect.
        // If the key is always non-unique, then the app will always redirect
        // to the first instance. In practice, the app should produce a key
        // that is sometimes unique and sometimes not, depending on its own needs.
        uint number = CryptographicBuffer.GenerateRandomNumber();
        string key = (number % 2 == 0) ? "even" : "odd";
        var instance = AppInstance.FindOrRegisterInstanceForKey(key);
        if (instance.IsCurrentInstance)
        {
            // If we successfully registered this instance, we can now just
            // go ahead and do normal XAML initialization.
            global::Windows.UI.Xaml.Application.Start((p) => new App());
        }
        else
        {
            // Some other instance has registered for this key, so we'll 
            // redirect this activation to that instance instead.
            instance.RedirectActivationTo();
        }
    }
}

對於 key 的構造和判斷,以及判斷後的處理,是多實例重定向的關鍵,我們先看看 FindOrRegisterInstanceForKey(key) 和 IsCurrentInstance 的註釋:

//
// 摘要:
//     如果另一個實例已註冊該密鑰,使用平臺註冊一個應用實例,或查找現有實例。
//
// 參數:
//   key:
//     作為實例密鑰的非空字元串。
//
// 返回結果:
//     表示已註冊密鑰的第一個應用的應用實例。
public static AppInstance FindOrRegisterInstanceForKey(string key);

//
// 摘要:
//     應用的當前實例是否是該實例定義的特定密鑰的已註冊實例。
//
// 返回結果:
//     指示當前應用是否為該應用的已註冊實例的布爾值。
public bool IsCurrentInstance { get; }

 

後臺任務和多實例

關於後臺任務的多實例,官方有以下說明:

  • 進程外的後臺任務支持多實例,通常,每個新觸發的結果會獨立在一個後臺任務的實例中;
  • 進程內的後臺任務不支持多實例;
  • 後臺音樂任務不支持多實例;
  • 當應用註冊一個後臺任務時,它通常會首先檢查這個任務是否已經註冊了,如果已註冊,或刪除重新創建它,或維持當前的註冊。這也是多實例應用的典型特點。然而,多實例應用可能會選擇在每個實例的基礎上註冊一個不同的後臺任務名。這對導致多次註冊相同的觸發器,並且觸發器觸發時將會激活多個任務實例;
  • 應用服務會為每一個應用服務後臺任務的連接啟動一個單獨的實例,這對多實例應用保持不變,即多實例應用的每個實例都會獲得自己的應用服務後臺任務實例;

 

其他註意事項

關於多實例應用,官方文檔還提示了一些額外的註意事項:

  • 支持多實例應用的 UWP 應用,只能面向傳統桌面系統和 IoT;
  • 為避免競爭條件和資源爭奪的問題,多實例應用需要採取措施,分區和同步許可權到對訪問進行設置,應用本地存儲和任何其他資源(如用戶文件,數據存儲等),以在多個實例間完成共用。標準的同步機制包括 mutexes,semaphores,events 等都是可用的;
  • 如果應用的 Package.appxmanifest 文件中存在 SupportsMultipleInstances 欄位,那麼他的擴展中不需要再聲明 SupportsMultipleInstances;
  • 如果你把 SupportsMultipleInstances 添加到除後臺任務,應用服務之外的的任何其他擴展中,並且托管該擴展的應用沒有在 Package.appxmanifest 中聲明 SupportsMultipleInstances,則會發生模式錯誤;
  • 應用可以在 manifest 中使用 ResourceGroup 來把多個後臺任務分組到同一個宿主中, 這和多實例是衝突的,每個活動都會出現在單獨的宿主中。因為一個應用不能同時聲明 SupportsMultipleInstances 和 ResourceGroup;

 

多實例應用的介紹就到這裡,大家可以結合自己應用的實際場景,更加合理的設置 key 和判斷條件來使用多實例,謝謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.超類和子類的設計;2.建立繼承層次;3.覆蓋方法。 程式StringLister:使用數組列表和特殊的for迴圈將一系列字元串按字母順序顯示到屏幕上。這些字元串來自一個數組和命令行參數 1 package com.jsample; 2 3 import java.util.*; 4 5 publ ...
  • 以前用python,go嘗試在linux下做web服務,python沒有強類型支持與高性能,go又沒有很好的集成開發環境(還有強迫症的語法),回頭看了幾次.net,都沒有時間嘗試,現終於實現了這些想法,與大家分享。做web大項目,做工程,必須要有稱手的工具幫我調試、測試、開發。工程化很重要,VS是一 ...
  • 在視窗屬性界面添加事件服務 ...
  • 最近用EF做了幾個小東西,瞭解簡單使用後有了深入研究的興趣,所以想系統的研究一下EF CodeFist的幾個要點。下麵簡單列一下目錄 1.1 目錄 1. 資料庫初始化策略和數據遷移Migration的簡單介紹 3. 配置一對一關係 4. 配置一對多關係 5. 配置多對多關係 6. 開發環境配置Mig ...
  • 對於主外鍵約定的理解,其實是學習實體間一對一和一對多關係的基礎。 1.1 主鍵(Key)約定 主鍵的預設約定是: 只要欄位名為 實體名(類名)+"id"(不區分大小寫) ,這就算是預設的主鍵約定。 如果要顯示標識的話,就使用特性標簽進行標識: 這樣標識的主鍵,在資料庫的名稱就是 StudentKey ...
  • 1.需求 WPF本身沒有直接把點集合繪製成曲線的函數。可以通過貝塞爾曲線函數來繪製。 貝塞爾曲線類是:BezierSegment,三次貝塞爾曲線,通過兩個控制點來控制開始和結束方向。 QuadraticBezierSegment,二次貝塞爾,通過一個控制點來控制彎曲方向。 本文使用的是三次。 圖片來 ...
  • 1,進入nginx的html目錄 vim ./crossdomain.xml 具體路徑: /usr/local/nginx/html/crossdomain.xml 2,在crossdomain.xml中添加: 1 2 3 4 5 6 結果就是: 註意:預設/usr/local/nginx/html ...
  • 在安裝 nginx 伺服器後,我想把網站的根目錄設置為 /root/www/ ,於是對 nginx 的 nginx.conf 文件進行配置 先打開 nginx.conf #user nobody; worker_processes 1; #error_log logs/error.log; #err ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...