概述

前面一篇 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. JAVA在不确定具体 Annotation 类型时,获得注解参数

       package com.lzw.demo; @SpringBootApplication public class DemoApplication { public static void ma ...

  2. Hive导入HDFS/本地数据

    #创建表人信息表  person(String name,int age) hive> create table person(name STRING,age INT)ROW FORMAT DE ...

  3. Django使用模板后无法找到静态资源文件

    Django使用模板后无法找到静态资源文件 环境配置 Django版本1.11 python版本3.6.2 前言 在编写Django网站的时候,在涉及模板方面,一些简单的例子都没有问题,但这些例子都有 ...

  4. Caffe、TensorFlow、MXnet三个开源库对比

    库名称 开发语言 支持接口 安装难度(ubuntu) 文档风格 示例 支持模型 上手难易 Caffe c++/cuda c++/python/matlab *** * *** CNN ** MXNet ...

  5. JAVA之编码---->CSV在文本下是正常的,用EXCEL打开是乱码的问题

    JAVA之编码---->CSV在文本下是正常的,用EXCEL打开是乱码的问题 在JAVA下输出文件流,保存成CSV(用UTF-8)文件,怎么处理用EXCEL下是乱码,但是在记事本等其他软件都是正 ...

  6. 利用PowerDesigner15在win7系统下对MySQL 进行反向工程(三)

    利用PowerDesigner15在win7系统下对MySQL 进行反向工程 1.选择"数据库-->Generate Database...",查看数据库表的SQL语句 2. ...

  7. mobile开发中常用的css

    1. viewport: 也就是可视区域.对于桌面浏览器,我们都很清楚viewport是什么,就是出去了所有工具栏.状态栏.滚动条等等之后用于看网页的区域, 这是真正有效的区域.由于移动设备屏幕宽度不 ...

  8. 芝麻HTTP:在阿里云上测试Gerapy教程

    1.配置环境 阿里云的版本是2.7.5,所以用pyenv新安装了一个3.6.4的环境,安装后使用pyenv global 3.6.4即可使用3.6.4的环境,我个人比较喜欢这样,切换自如,互不影响. ...

  9. http协议的补充二

    一,浏览器到服务器request 1.1,浏览器里面的内容 请求(浏览器->服务器) GET /day09/hello HTTP/1.1 Host: localhost:8080 User-Ag ...

  10. 拥抱.NET Core系列:MemoryCache 缓存域

    在上一篇“<拥抱.NET Core系列:MemoryCache 缓存选项>”我们介绍了一些 MSCache 的机制,今天我们来介绍一下 MSCache 中的缓存域. MSCache项目 M ...