当在计算机上调用特定触发器时,在 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.exe
IL)中运行,而主桌面项目将在中等 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>
此外,在清单文件中,BackgroundTask 的 EntryPoint 设置为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 相关的所有逻辑,以便通过启动另一个进程或在线程池线程中运行来执行。 有关详细信息,请参阅 CreateThread 和 CreateProcess。