【发布时间】:2018-10-07 17:38:04
【问题描述】:
我正在开发一个 UWP 应用程序,它使用进程内后台任务来下载新的 GitHub 通知并将它们显示为 toast 通知。我正在使用 MVVM 灯。我尝试使用 TimeTrigger 进行进程内后台任务,当应用程序处于前台或最小化时,一切都按预期工作。但是当应用程序关闭时,后台任务停止工作。监控任务管理器后,发现后台任务启动但刚启动就关闭了。所以我使用 ExtendedExecutionSession 来延长暂停时间。仍然无法正常工作。使用进程外后台任务解决了以前的问题,但引入了一个新问题。由于无法访问调用 API 所需的应用数据(GitHub Auth Data),GitHub api 调用在后台失败。
简而言之,我有以下问题:
- 当应用关闭时,进程中的后台任务不会在后台运行
- 当我使用 Octokit 对 GitHub 进行 API 调用时,进程外的后台任务可以共享应用程序数据(例如,在我的例子中是 GitHub Auth 数据)
我找到了以下解决方法:
- 将 ExtendedExecutionSession 与正在进行的后台任务一起使用
- 在进程外后台任务中使用进程间通信
我的问题是:
我应该如何以及何时在 In-process 任务中调用 ExtendedExecutionSession。
如何编写进程间通信以便能够从后台应用访问应用数据
请注意,我已在 MainPage.xaml.cs 中注册了后台任务。这是代码sn-p:
var syncBuilder = Helpers.BackgroundTaskHelper.BuildBackgroundTask(
"SyncNotifications",
new TimeTrigger(15, false),
internetAvailableCondition,
userPresentCondition,
sessionConnectedCondition
);
syncBuilder.IsNetworkRequested = true;
syncBuilder.Register();
我覆盖了 App.xaml.cs 中的 OnBackgroundActivated。这是代码片段:
var deferral = args.TaskInstance.GetDeferral();
args.TaskInstance.Task.Completed += BackgroundTask_Completed;
var taskName = args.TaskInstance.Task.Name;
switch (taskName)
{
case "ToastNotificationBackgroundTask":
await CoreApplication
.MainView
.CoreWindow
.Dispatcher
.RunAsync(
CoreDispatcherPriority.Normal,
async () =>
{
var toastTriggerDetails = args.TaskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
var toastArgs = QueryString.Parse(toastTriggerDetails.Argument);
var notificationId = toastArgs["notificationId"];
if (!notificationId.IsNulloremptyOrNullorwhitespace())
{
await NotificationsService.MarkNotificationAsRead(notificationId);
}
});
break;
case "SyncNotifications":
await CoreApplication
.MainView
.CoreWindow
.Dispatcher
.RunAsync(
CoreDispatcherPriority.Normal,
async () =>
{
AppViewmodel.UnreadNotifications = await NotificationsService.GetAllNotificationsForCurrentUser(false, false);
await AppViewmodel.UnreadNotifications?.ShowToasts();
});
break;
}
【问题讨论】:
-
您是否检查过您的代码在前台应用未运行时是否崩溃?要记住的一件事是,您的应用在未运行时没有视图,因此如果您的后台任务代码假设有视图,它可能会失败/崩溃。特别是在您的代码中,我看到它取决于 CoreApplication.MainView - 在后台激活期间可能为空。
-
另一件要检查的是你的延期。我看不到您何时/如何完成它。如果它只是在方法结束时超出范围,那么它将被标记为完成,并且任务将立即退出,在您的调度程序操作有机会运行完成之前。你需要坚持推迟,直到你真正完成你的任务。仔细想想,这很可能是您遇到的问题。
-
@StefanWickMSFT 编辑这篇文章是个错误。我实际上在代码末尾使用了
deferral.Complete();。 -
我也试过不使用
CoreApplication.MainView并得到相同的结果。 -
请澄清您所说的“代码结束”是什么意思。您是指方法结束,还是在您实际完成任务之后?您还检查过您的代码是否在这里遇到异常/崩溃?
标签: c# uwp background-task