0

我正在同步UWP APP. 我正在使用后台任务和ApplicationTrigger. 如果我调试我的代码(我的意思是如果附加了调试器)它可以工作,但是如果我运行已安装的应用程序,后台任务会在 10-20 分钟后终止。我必须同步很多文件,这需要 1-2 小时(我知道这很疯狂)。我在这里找到了信息: https ://msdn.microsoft.com/en-us/windows/uwp/launch-resume/handle-a-cancelled-background-task ,但我不确定是否是这样,因为一切有内存就OK。

“注意对于除台式机以外的所有设备系列,如果设备内存不足,则可能会终止后台任务。如果没有出现内存不足异常,或者应用程序未处理该异常,则后台任务将在没有警告的情况下终止并且不引发 OnCanceled 事件。这有助于确保应用程序在前台的用户体验。您的后台任务应该设计为处理这种情况。

    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        deferral = taskInstance.GetDeferral();
        _taskInstance = taskInstance;

        var details = taskInstance.TriggerDetails as ApplicationTriggerDetails;

        IEnumerable<string> filesUrls = details.Arguments.Select(x => x.Value as string).Distinct().ToList();
        filesCount = filesUrls.Count();

        downloader = CompletionGroupTask.CreateBackgroundDownloader();

        var result = await Download(filesUrls, taskInstance, downloader);
        if (result)
        {
            await Download(failedDownloads, taskInstance, downloader);
        }
        downloader.CompletionGroup.Enable();
        deferral.Complete();
    }

    private async Task<bool> Download(IEnumerable<string> filesUrls, IBackgroundTaskInstance taskInstance, BackgroundDownloader downloader)
    {
        bool downloadFailed = false;
        failedDownloads = new List<string>();
        foreach (string url in filesUrls)
        {
            DownloadOperation download = null;
            var uri = new Uri(url);
            try
            {
                download = downloader.CreateDownload(uri, await CreateResultFileAsync(url.Split('/').Last()));
                Task<DownloadOperation> startTask = download.StartAsync().AsTask();
                await startTask.ContinueWith(task => OnDownloadCompleted(task, url));
            }
            catch
            {
                downloadFailed = true;
                failedDownloads.Add(url);
            }
        }
        return downloadFailed;
    }


    private void OnDownloadCompleted(Task<DownloadOperation> task, string url)
    {
        if (task.Status == TaskStatus.RanToCompletion)
        {
            completedDownloads++;
            decimal progress = (completedDownloads / filesCount) * 100;
            _taskInstance.Progress = Convert.ToUInt32(progress);

        }
        else if(task.Status == TaskStatus.Faulted)
        {
            failedDownloads.Add(url);
        }
    }

    private async Task<IStorageFile> CreateResultFileAsync(string fileName)
    {
        var local = ApplicationData.Current.LocalFolder;
        IStorageFile resultFile = await local.CreateFileAsync(fileName, CreationCollisionOption.FailIfExists);
        return resultFile;
    }
}

有谁知道为什么我的任务被杀死?

4

2 回答 2

3

为创作者更新而更新

现在有一个名为extendedBackgroundTaskTime 的受限功能,可用于使后台进程在需要时运行1 到2 小时。它不会被 Windows Store 接受,但适用于侧面加载的 Line-Of-Business 应用程序并提交到 Windows Store for Business:https ://docs.microsoft.com/en-us/windows/uwp/packaging/应用程序能力声明

目前没有任何方法可以为提交到应用商店的应用程序运行 1 到 2 小时的真正无头后台同步。这种类型的同步可以异步和分块完成。BackgroundUploader 和 BackgroundDownloader 类是对单个文件进行网络传输的选项,然后根据每个文件的下载完成情况将其唤醒以进行工作。如果同步可以等到设备处于 AC 连接状态,则维护触发器也可以注册为定期唤醒并运行 10 分钟以完成大量同步工作。

如果您的应用程序可以在前台并最小化,那么未指定的扩展执行可能是一个不错的选择。它也是电池感知的,但如果他们的应用程序处于交流连接状态并且没有尝试进入连接待机,那么它可以无限期地运行。此方法通常用于具有多任务处理的媒体或其他项目编辑活动,但可能是您可以采用的一种方法。

于 2016-10-20T16:40:22.800 回答
1

您的后台任务通过 BackgroundTaskCancellationReason = ExecutionTimeExceeded被取消,因为如果应用程序正在运行,则使用 ApplicationTrigger 的后台任务允许运行的最长时间为 10 分钟。如果应用程序被挂起,则允许使用 ApplicationTrigger 的后台任务最多运行 5 分钟。如果达到此时间限制,操作系统将使用 BackgroundTaskCancellationReason = IdleTask取消任务。

在您的后台任务中,将此代码放在 Run 方法的开头,以便在 toast 中查看取消原因。

        taskInstance.Canceled += (s, e) => {
            var toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
            var toastTextElements = toastXml.GetElementsByTagName("text");
            toastTextElements[0].InnerText = e.ToString();
            ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastXml));
        };
于 2016-05-23T22:47:45.830 回答