Windows 8 中使用后台任务

Windows 应用商店应用程序调试入门

Bruno Terkaly
Robert Evans

20 世纪 40 年代,Admiral Grace Hopper 的一个程序无法正常运行,随后她发现,一只飞蛾卡在了 Harvard Mark II 上的两个继电器之间,“bug”这一术语由此而来。 当然,现如今,调试与虫子毫无关系。 调试是查找并清除软件缺陷的过程。

尽管现在的编程语言和工具能够大大帮助开发者编写可靠代码,但仍无法避免逻辑错误。 现代编译器只能对类型系统的编程语言语法和适当使用执行基本检查。 编译器几乎无法帮助您确定应用程序的实际运行时行为。 因此,调试技能非常重要。 本文将集中介绍如何调试 Windows 应用商店应用,并探讨在此领域中使用的一些技巧。

我们将使用 Visual Studio 2013 Preview,但这些技巧通常将与此产品的先前版本配合使用。 不过在开始之前,您需要准备环境,以提供比单独使用 Visual Studio 更为高级的调试功能。 我们建议您下载并安装以下资源:

进程生命周期管理

对于典型桌面应用程序,用户在启动应用程序后,应用程序将一直运行,直至用户将其终止。 即使不在前端,应用程序也将继续运行。 Windows 应用商店应用程序则有所不同。 当应用程序不在前端时,运行时代理程序这一 Windows 服务将挂起此应用程序中的所有线程,并仅当应用程序回到前端时重新将线程唤醒。 此新颖功能可帮助维持整体系统性能和电池寿命。 在 Windows 8.1 中,即使用户将应用程序关闭,默认操作仍会将此应用程序置入挂起状态而非将其终止。 如果您愿意使用先前的 Windows 8 功能,可将 Windows.ApplicationModel.ClosePolicy.TerminateOnClose 设置为 True。

挂起和继续事件均将发送至应用程序,您可以存储和检索状态,或根据需要采取其他操作。 此外,如果应用程序施加的内存压力过多或启动时间过长,则运行时代理程序将终止此应用程序并结束所有线程。 无论是调试自有应用程序还是附加到已安装的应用程序(使用“调试”|“调试安装的应用程序包”),Visual Studio 均将对接受调试的应用程序自动禁用进程生命周期管理 (PLM)。 禁用 PLM 非常重要,因为 PLM 会使您无法适当调试应用程序。 原因很简单,运行时代理程序可能会介入并终止应用程序,导致您无法适当调试。

不过,对于 Visual Studio 以外的一些调试器(例如 Windows 调试器 (WinDbg) 和 Microsoft Console Debugger (CDB)),您需手动禁用 PLM 功能。 要手动禁用 PLM,可使用 Windows 8.1 SDK 提供的 PLMDebug 工具。 PLMDebug 是命令行工具,可用于通过 /enableDebug 开关对特定 .appx 包禁用 PLM。 您可通过 Windows PowerShell 命令 Get-AppxPackage 或通过 Process Explorer(如本文稍后所述)查看所有安装的应用程序包,以确定特定 .appx 包的 ID。

PLMDebug 提供多种易用功能。 例如,它可使您将各种事件显式发送至应用程序,包括挂起、继续、终止、强制终止和干净终止。 还可使您附加实时调试器(本文不述及此内容)。

通过 Visual Studio,您还可使用“调试位置”工具栏(默认情况下不显示)触发挂起和继续事件。 可通过选择“视图”|“工具栏”|“调试位置”添加此工具栏。 调试选项将在您主动调试应用程序时启用。 图 1 显示了 Visual Studio 2013 Preview 中的“调试位置”工具栏。

The Debug Location Toolbar
图 1“调试位置”工具栏

后台任务

许多方案(例如更新动态磁贴)可以在不使用后台任务的情况下完成,但有时必须使用后台任务,后台任务提供了另一种方式,可使 Windows 应用商店应用中的代码由于您定义的特定系统条件而隐式启动。 例如,您可能需要在后台中为一个应用程序添加或创建缩略图,但只想在设备使用交流电源时执行此操作。 通过维护触发器,您可基于时间间隔和系统条件启动某些任务,还可重复执行任务。 用于后台任务的代码在应用程序中定义,但在大多数情况下,此代码通过名为 BackgroundTaskHost 的单独进程执行。

Windows 应用商店应用程序通过使用 BackgroundTaskBuilder 类,在操作系统级别后台任务基础架构中注册其后台任务。 后台任务作为实施 IBackgroundTask 界面的类而创建,您只需实施 Run 方法。 后台任务必须拥有一个触发器以及一个或多个条件集(用于说明启动后台任务的确切情况)。 触发器通过 BackgroundTaskBuilder 类的 SetTrigger 方法指定。

通过 Visual Studio,可轻松查找和调试注册的后台任务,这是因为“调试位置”工具栏将显示应用程序声明的后台任务,并可通过 Visual Studio 可视界面将其启动。 此技巧适于启动所有后台任务,但使用 ControlChannelTrigger、PushNotificationTrigger 或触发器类型为 SmsReceived 的 SystemTrigger 的后台任务除外。 有关详细信息,请参阅 aka.ms/O35jqc 上的《后台任务简介》白皮书。 您可在 bit.ly/IZpfqN 上找到很好的代码示例。

激活

可通过多种方法启动应用程序,具体取决于您实施的内容,例如文件、协议、PrintTaskSettings 或 ShareTarget。 例如,当用户从其他应用程序与您的应用程序共享时,ShareTarget 激活类型将处于活动状态。

Windows 8.1 的激活功能有一些变化。 例如,搜索激活功能已被弃用,但仍提供一些向后兼容支持。 此外,还提供了一种新的创新方法,用于启动与您的应用程序共享屏幕的其他应用程序。 这意味着在应用程序仍处于活动状态时,可与浏览器共享屏幕。 有关此功能的详细信息,请参阅 bit.ly/11ckVS3

要从任一激活类型调试应用程序,第一步是转到应用程序项目属性“启动操作”。 在 Visual Studio 解决方案资源管理器中,右键单击“ContosoCookbook”并选择“属性”以启动。 选择复选框“不启动,但在启动时调试代码”(如图 2 所示)。 通过此设置,您可调试应用程序,并将断点置入 OnLaunched 处理程序,当任何其他激活类型将其激活时,此处理程序将被触发。 此设置可在您启动调试器任务时,通知应用程序为调试做好准备但不实际启动。 应用程序仅将等待。

Setting Debugger Properties
图 2 设置调试器属性

探讨正在运行的应用程序

Process Explorer 提供了一些有用功能,帮助您了解正在运行的应用程序的内部工作情况。 为了解这些功能,我们将探讨名为 Kids Car Colors 的应用程序中的一些代码,您可从 bit.ly/YnmAxT 下载此应用程序。 转到开始屏幕并启动 Kids Car Colors 应用程序,然后启动 Process Explorer(假设您先前已对其进行设置)。

展开 svchost.exe 后,您将看到运行时代理程序和所有正在执行的 Windows 应用商店应用(如图 3 所示)。 右键单击 KidsCarColors.exe,您可查看属性(例如根文件夹安装)。

Process Explorer from SysInternals
图 3 SysInternals 的 Process Explorer

Process Explorer 中的应用程序“Properties”窗口提供大量信息。 例如,如图 4 所示,您可在“Image”选项卡中查看给定已安装应用程序的位置。 内置应用程序和从 Windows 应用商店下载的应用程序始终安装在 [根文件夹]\Program Files\Windows Apps 文件夹中。

Properties of the Kids Car Colors App
图 4 Kids Car Colors 应用程序的属性

您还会发现“.NET Performance”选项卡非常有用;它提供基本性能计数器信息,包括堆大小、第 0 代回收次数和垃圾回收 (GC) 所用时间的百分比等。 通过查看这些性能计数器,您可评估 GC 的有效性,GC 机制可在不再引用对象时释放内存。 要在不需要内存时以更积极的方式释放内存,可能需修改应用程序的代码。 如需了解有关 .NET 性能计数器的更多信息,请访问 msdn.microsoft.com/library/w8f5kw2e

您可能需要更改 C:\Program Files\Windows Apps 文件夹的所有权和权限,才能查看其中的应用程序。

在 C:\Program Files\Windows Apps 中,每个已安装应用程序均具有并行文件夹。 每个应用程序文件夹均包含大量信息(如下一部分所述)。

探讨代码

如前所述,您可转到单个应用程序的安装目录,并查找有关此应用程序的大量信息,例如所有 MP3 文件(如果有)、图像、XAML 文件和其他资源。 不过,无法查看 Windows 8.1 应用程序中的 XAML 文件,因为这些文件已编译到二进制文件中。 但您可通过多种工具反编译使用 C# 和 Visual Basic .NET 编写的 Windows 应用商店应用可执行文件。

我们将使用 Telerik 的 JustDecompile 工具反编译 KidsCarColors.exe。 反编译是使用应用程序二进制文件并生成可读源代码的过程。 为此,您只需导航到应用程序的安装文件夹(如先前所述),右键单击 KidsCarColors.exe 并选择“Open with JustDecompile”。 如图 5 所示,您现在可看到反编译程序显示的代码低级别详细信息。 请注意,应用程序内的数据模型易于解密和浏览。 使用 JustDecompile,可轻松恢复丢失的源代码,或查看程序集以找出外部 bug 的根本原因。 这意味着您可查看几乎任何已安装 Windows 应用商店应用的源代码。

Decompiling KidsCarColors.exe
图 5 反编译 KidsCarColors.exe

此工具可提供大量信息。 在创建 Kids Car Colors 时,为了在儿童单击汽车颜色时得到良好的声音效果,着实花费了一番功夫。 但所有相关代码现在都是公开的。 如果在 JustDecompile 项目资源管理器中导航到 ItemDetailPage 对象,即可发现声音文件的确切工作方式:从本地存储检索 MP3,实例化各个 MediaElement,注册媒体回拨事件,调用 SetSource 等。 如果有人想要复制此方法,所有内容就在这里,向全世界公开。

JustDecompile 在其工具栏上提供了几个按钮,包括“Assembly List”按钮,此按钮可使您浏览应用程序已设置的引用。 知晓 Windows 应用商店应用已设置的引用后,即可了解此应用程序所使用功能的一些相关信息。 例如,您可看到 Kids Car Colors 使用了 Advertising SDK。 这有作用,因为此应用程序显示广告。 不过从理论上,您可设置对未使用的程序集的引用。 假设我们删除了应用程序内的广告,但忘记删除对 Advertising SDK 程序集的引用。 通过 JustDecompile,您可查看在外部运行的确切版本以及代码和引用的情况。

JustDecompile 还提供名为 Find Usages 的功能,可用于将“Find All References”命令复制到 Visual Studio 中。 只需按住 Ctrl 键并单击反编译代码中的任何命名空间、类型或成员,即可获得包含所有相应代码引用的列表。 这非常有助于您了解应用程序如何在没有任何源代码的情况下运行。

总结

要最大限度提高您作为 Windows 应用商店应用开发者的效率,必须充分了解如何调试应用程序。 本文简要概述了您在代码中查找和修复问题时可使用的一些工具和技巧。 此外,某些技巧还可帮助您在没有源代码的情况下,了解其他 Windows 应用商店应用的工作原理。

Bruno Terkaly是 Microsoft 的开发推广人员。他的知识深度来源于多年来相关领域以及使用大量平台、语言、框架、SDK、库和 API 编写代码的经验。他不辞辛苦,就有关构建基于云的应用程序(特别是使用 Windows Azure 平台)编写代码、发布博客并给予现场演示。您可以阅读他的博客 blogs.msdn.com/b/brunoterkaly

Robert Evans是首席现场工程师,也是 Windows 8:Windows 应用商店应用程序实验室的技术负责人。他是 Microsoft 认证专业开发者,也是 Windows 8 Dev Bootcamp 主讲师。除了参加无数 Windows 8 黑客马拉松活动外,他还在 TechReady、GeekReady 和 The Tablet Show 等活动上演讲,并在 Microsoft Build 大会上主持了 Windows 8 硬件实验室。在成为首席现场工程师之前,Evans 在 Microsoft 从事过 12 年的软件开发工作,在 Microsoft IT 部门负责各种产品(如 Xbox Live、MSN、Mobile Engineering)的开发。您可在 aka.ms/Utg864 上阅读他在首席现场工程部博客上撰写的文章。

衷心感谢以下技术专家对本文的审阅:Christophe Nasarre-Soulier (Microsoft)
Christophe Nasarre 在 Microsoft 的开发支持团队中工作。 从 1996 年开始,他担任过多部书籍的技术编辑,还为 MSDN 杂志撰写了许多文章。