后台任务迁移策略

当在计算机上调用特定触发器时,在 UWP 应用中大量使用后台任务来执行作业。 由于这些服务不需要任何服务运行侦听触发器,因此它非常高效。 因此,在将 UWP 应用迁移到 WinUI 3 和其他使用 Windows 应用 SDK 的桌面应用时,开发人员可能需要支持在平台上实现后台任务。

UWP 应用模型中提供的后台任务可以是进程外任务,也可以是进程内任务。 本文介绍在 Windows 应用 SDK 中迁移到 BackgroundTaskBuilder API 时每种类型的迁移策略。

进程外后台任务

对于 UWP 中的非过程后台任务,后台任务将编写为 Windows 运行时(WinRT)组件,该组件在注册期间设置为 BackgroundTaskBuilder 上的 TaskEntryPoint。 迁移到 Windows 应用 SDK 时,开发人员可以保留此 as-is,并将 WinRT 组件与桌面项目打包在一起。 在这种情况下,在调用触发器时,中转站基础结构将启动 backgroundtaskhost 进程,并且将在进程中执行 WinRT 组件后台任务。 在此方法中,后台任务将在低完整性级别(IL)进程(backgroundtaskhost.exeIL)中运行,而主桌面项目将在中等 IL 进程中运行。

如果应用程序需要在中等 IL 进程本身中运行后台任务,则需要将完全信任 COM 组件用于后台任务。 在这种情况下,开发人员必须使用 Windows 应用 SDK BackgroundTaskBuilder 注册完全信任 COM 组件。 请注意,Windows.ApplicationModel.Background 命名空间中的 BackgroundTaskBuilder API 会在注册某些触发器时引发异常。

可以在 GitHub 上找到完整的 WinUI 3 后台任务注册示例。

此处提供了有关实现的更多详细信息。 唯一必需的更改是将 WinRT BackgroundTaskBuilder API 替换为 Windows 应用 SDK API Microsoft.Windows.ApplicationModel.Background.BackgroundTaskBuilder

进程内后台任务

对于 UWP 中的进程内后台任务,后台任务例程在 OnBackgroundActivated 回调中实现,该回调作为前台进程的一部分运行。 由于 OnBackgroundActivated 回调不可用,因此无法在 WinUI 3 应用程序中执行此作。 应用程序需要将后台任务的实现转移到完全信任的 COM 任务中,并在包清单中定义 COM 服务器,以处理任务的 COM 激活。 当触发器发生时,COM 激活将在注册于触发器的相应 COM Coclass 上发生。

可以在 GitHub 上找到完整的 WinUI 3 后台任务注册示例。

此处提供了有关实现的更多详细信息。 唯一的更改是将 WinRT BackgroundTaskBuilder API 替换为 Microsoft.Windows.ApplicationModel.Background.BackgroundTaskBuilder 中的 Windows 应用 SDK API。

Windows 应用程序 SDK 的后台任务生成器 API

此 Windows 应用 SDK BackgroundTaskBuilder API 是为了支持使用 Windows 应用 SDK 的 WinUI 3 和其他桌面应用程序中的完全信任 COM 后台任务实现而创建的,因为除了几个触发器外,WinRT API 在注册过程中会抛出异常。

以下代码演示如何使用 Windows 应用 SDK BackgroundTaskBuilder API 注册后台任务:

//Using Windows App SDK API for BackgroundTaskBuilder
winrt::Microsoft::Windows::ApplicationModel::Background::BackgroundTaskBuilder builder;
SystemTrigger trigger = SystemTrigger(SystemTriggerType::TimeZoneChange, false);
auto backgroundTrigger = trigger.as<IBackgroundTrigger>();
builder.SetTrigger(backgroundTrigger);
builder.AddCondition(SystemCondition(SystemConditionType::InternetAvailable));
builder.SetTaskEntryPointClsid(classGuid);
builder.Register();

下面是等效的 C# 代码:

// Using Windows App SDK API for BackgroundTaskBuilder
var builder = new Microsoft.Windows.ApplicationModel.Background.BackgroundTaskBuilder();
var trigger = new SystemTrigger(SystemTriggerType.TimeZoneChange, false);
builder.SetTrigger(trigger);
builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
builder.SetTaskEntryPointClsid(classGuid);
builder.Register();

若要使用此 API,请将以下标记添加到项目文件以启用 Windows 应用 SDK 后台任务:

<WindowsAppSDKBackgroundTask>true</WindowsAppSDKBackgroundTask>

此外,在清单文件中,BackgroundTaskEntryPoint 设置为Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.Task

<Extension Category="windows.backgroundTasks" EntryPoint="Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.Task">
    <BackgroundTasks>
        <Task Type="general"/>
    </BackgroundTasks>
</Extension>

对于 C# 应用程序,还应将 ActivatableClass 注册添加到清单文件:

<Extension Category="windows.activatableClass.inProcessServer">
    <InProcessServer>
        <Path>Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.dll</Path>
        <ActivatableClass ActivatableClassId="Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.Task" ThreadingModel="both"/>
    </InProcessServer>
</Extension>

利用 TaskScheduler 进行后台任务迁移

任务计划程序 可帮助桌面应用实现 UWP 应用中 BackgroundTaskBuilder 提供的相同功能。 此处提供了有关使用 TaskScheduler 实现的更多详细信息。

在 Windows 应用 SDK 应用程序中使用 ApplicationTrigger

UWP 应用程序中支持 ApplicationTrigger,因为生存期管理方案可以暂停应用程序进程。 WinUI 和其他 Windows 应用 SDK 桌面应用程序不会发生此方案,因此 WinUI 应用程序中不支持此触发器。 需要重写与 ApplicationTrigger 相关的所有逻辑,以便通过启动另一个进程或在线程池线程中运行来执行。 有关详细信息,请参阅 CreateThreadCreateProcess