概述

前面一篇 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 % == ) ? "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 和判断条件来使用多实例,谢谢!

New Windows 10 SDK - Multi-instance UWP apps的更多相关文章

  1. About Windows 10 SDK Preview Build 17110

    在 Windows Developer Day 活动同时,微软正式 Release 了 Windows 10 SDK Preview Build 17110. Windows 10 SDK Previ ...

  2. New Windows 10 SDK - Toast Notification

    概述 Toast Notification 在 UWP App 中有很重要的作用,能够很大程度上增强 App 和用户之间的沟通,比如运营推广活动.版本更新.提醒类任务提示等等.Toast Notifi ...

  3. Windows 10 SDK 10.0.10069 : The installer failed. User cancelled installation. Error code: -2147023294

    注* 请先跳到文章后面的配置“操作系统的区域设置”部分,然后尝试重试安装VS,如果仍然失败,请看下面内容. 安装UAP SDK失败 Visual Studio 2015 RC Community 安装 ...

  4. 修复Windows 10 SDK 17763中NavigationView上的AcrylicBrush丢失

    原文 修复Windows 10 SDK 17763中NavigationView上的AcrylicBrush丢失 Microsoft发布了新版本的Windows 10 UWP SDK Build 17 ...

  5. Windows 10 SDK 10.0.10158

    昨天微软发布了Windows 10 SDK 10158版本: http://blogs.windows.com/buildingapps/2015/06/30/windows-10-sdk-previ ...

  6. 被 Windows 10 SDK 坑了

    抓包抓到的配置文件与完整版的VS一致,虽然显示出来的只有 Windows 10 通用工具,我还以为是只更新这些(因为列出来的几个,我确实之前没装),就愉快地点了安装,结果……新建项目时,发现 Wind ...

  7. 自动启动 Windows 10 UWP 应用

    原文: https://docs.microsoft.com/zh-cn/windows/uwp/xbox-apps/automate-launching-uwp-apps 简介 开发人员有多种选项可 ...

  8. 打造理想的Windows 10 APP开发环境的5个步骤

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:微软即将发布Windows 10手机版,实际上很多人现在已经开始在开发Windows ...

  9. Windows 10 IoT Serials 10 – 如何使用OCR引擎进行文字识别

    1. 引言 OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方 ...

随机推荐

  1. UVA - 10118 Free Candies 记忆化搜索经典

    思路:d[a][b][c][d]表示从已经第一个篮子取了a颗糖,第二个取了b颗糖,第三个取了c颗糖,第四个取了d颗糖最多还能够获得多少糖果.首先明白一个问题:如果能分别取a,b,c,d个,不论如何取, ...

  2. day1(变量、常量、注释、用户输入、数据类型)

    一.变量 name = "SmallNine" 等号前面是变量名(标识符),等号后面是变量值 变量的主要作用:就是把程序运算的中间结果临时存到内存里,已备后面的代码继续调用. 变量 ...

  3. 吾八哥学Selenium(三):操作复选框checkbox/单选框radio的方法

    复选框checkbox和单选框radio是web网站里经常会使用到的两个控件,那么在web自动化测试的时候如何利用Selenium来操作这俩控件呢?今天我们就来简单入门练习一下! html测试页面代码 ...

  4. ORACLE ASMM与AMM的总结

      概念对比介绍 相信有些人会对ORACLE当中的AMM(Automatic Memory Management)与ASMM(Automatic Shared Memory Management)有些 ...

  5. mxnet:结合R与GPU加速深度学习

    转载于统计之都,http://cos.name/tag/dmlc/,作者陈天奇 ------------------------------------------------------------ ...

  6. 芝麻HTTP:Ansible扩展

    Ansible简介 Ansible是由Python开发的一个运维工具,因为工作需要接触到Ansible,经常会集成一些东西到Ansible,所以对Ansible的了解越来越多. 那Ansible到底是 ...

  7. tcp_wrapper

    介绍 对基于tcp协议开发并提供服务的应用程序,所提供的一层访问控制工具 基于库调用实现其功能 * 库名:libwrap 判断服务是否能够由tcp_wrapper进行访问控制 1. 动态编译 ldd命 ...

  8. h264多slice

    1, h264编码以macroblock为最小单位(简称MB),多个连续的MB组成一个slice,每个slice编码输出一个NALU 2, 划分slice的方式可以按照固定个数MB的方式: 也可以以对 ...

  9. Web原理

    在日常学代码的过程中,总会多多少少遇到点瓶颈.但是别人又听得懂,这是为什么? 我觉得,就是在原理上都不去思考,为什么这样写?为什么一定要这样写?那到底该怎么写?写完了是怎么运行的? 就以上几个问题,只 ...

  10. jquery中ajax序列化提交form表单的几种方法。

    一,ajax主流的方法 $.ajax({ type: 'post', url: 'your url', data: $("form").serialize(), success: ...