I'm syncing files in UWP APP. I'm using a background task and ApplicationTrigger. If I debug my code (I mean if a debugger is attached) it works, but if I run installed application, the background task is terminated after 10-20 minutes.
I have to sync a lot of files and it will take 1-2h (I know it's crazy).
I found info here:
https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/handle-a-cancelled-background-task, but I'm not sure if this is it, because everything with memory is OK.
"Note For all device families except desktop, if the device becomes low on memory, background tasks may be terminated. If an out of memory exception is not surfaced, or the app does not handle it, then the background task will be terminated without warning and without raising the OnCanceled event. This helps to ensure the user experience of the app in the foreground. Your background task should be designed to handle this scenario."
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;
}
}
Does anyone know why my task is killed?
Your background task gets cancelled with BackgroundTaskCancellationReason = ExecutionTimeExceeded because the maximum time allowed for a background task with ApplicationTrigger to run is 10 minutes if the app is running. If the app is suspended, a background task with ApplicationTrigger is allowed to run for a maximum of 5 minutes. If this time limit is reached, the OS will cancel the task with BackgroundTaskCancellationReason = IdleTask.
In your background task put this code at the beginning of the Run method to see the cancellation reason in a toast.