[UWP]后台任务在10-20分钟后终止(下载文件)
本文关键字:终止 下载 文件 10-20分钟 UWP 后台任务 | 更新日期: 2024-10-19 21:26:02
我正在UWP APP
中同步文件。我正在使用后台任务和ApplicationTrigger
。如果我调试我的代码(我的意思是,如果附加了调试器),它会工作,但如果我运行已安装的应用程序,后台任务会在10-20分钟后终止。我必须同步很多文件,这需要1-2小时(我知道这太疯狂了)。我在这里找到了信息:https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/handle-a-cancelled-background-task,但我不确定是不是这样,因为所有有内存的东西都可以。
"注意:对于除台式机以外的所有设备系列,如果设备内存不足,后台任务可能会被终止。如果内存不足异常没有出现,或者应用程序没有处理它,则后台任务将在没有警告和引发的情况下终止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;
}
}
有人知道为什么我的任务被杀了吗?
为创建者的更新更新
现在有一个名为extendedBackgroundTaskTime的受限功能,如果需要,可以使用该功能使后台进程运行1到2个小时。它不会被Windows应用商店接受,但适用于侧面加载的业务线应用程序并提交到Windows应用商店for Business:https://learn.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations
对于提交到应用商店的应用程序,目前没有任何方法可以运行1小时到2小时的真正无头后台同步。这种类型的同步可以异步和分块进行。BackgroundUploader和BackgroundDownloader类是对单个文件进行网络传输的选项,然后根据每个文件的下载完成情况进行唤醒。如果同步可以等到设备处于AC连接状态,那么维护触发器也可以注册为定期唤醒并运行10分钟,以完成大量同步工作。
如果你的应用程序可以在前台并最小化,那么未指定的扩展执行可能是一个不错的选择。它也支持电池供电,但如果他们的应用程序处于交流连接状态,并且没有尝试进入连接待机状态,那么它可能会无限期运行。这种方法通常用于多任务处理的媒体或其他项目编译活动,但也可能是您可以采取的方法。
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));
};