Reputation: 155
I have code like below which is uploading data using a background task on a timer running every 15 minutes. When there is nothing to upload my log shows
WINDOWS SYNC SUCCESS: 0m:0s:813ms
However when there is actually data to upload this takes a little longer and I end up with 2 logs
WINDOWS SYNC CANCELLED AFTER: 0m:25s:108ms - ExecutionTimeExceeded WINDOWS SYNC SUCCESS: 0m:27s:617ms
I understand that I only have 25 seconds on the background task - however my question is why is my "finally" block being executed when the OnCancelled event is being triggered?
This does not always happen which is what confuses me. Often I just get the cancelled log. Will the finally block always get called?
Also - as an aside - when I was testing this I had the device in sleep mode when the background task was triggered - not sure if this is relevant.
public sealed class BackgroundSync : IBackgroundTask
{
CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
private DateTime startTime;
private DateTime endTime;
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
// Associate a cancellation handler with the background task.
taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCancelled);
try
{
await Task.Run(async () =>
{
startTime = DateTime.Now;
// MY PROCESSSING IN HERE
endTime = DateTime.Now;
});
}
catch (Exception e)
{
await DataNAVToMobile.InsertBackgroundLog("WINDOWS SYNC EXCEPTION: " + e.Message);
}
finally
{
TimeSpan timeSpan = endTime - startTime;
await DataNAVToMobile.InsertBackgroundLog("WINDOWS SYNC SUCCESS: " + String.Format("{0}m:{1}s:{2}ms",timeSpan.Minutes,timeSpan.Seconds,timeSpan.Milliseconds));
_deferral.Complete();
}
}
private void OnCancelled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
// The background task has been detected as idle or hung.
// Cancel all pending async operations and return from the task.
endTime = DateTime.Now;
TimeSpan timeSpan = endTime - startTime;
DataNAVToMobile.InsertBackgroundLog("WINDOWS SYNC CANCELLED AFTER: " + String.Format("{0}m:{1}s:{2}ms", timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds) + " - " + reason.ToString());
cancelTokenSource.Cancel();
}
Upvotes: 1
Views: 1188
Reputation: 5137
Background Tasks are limited to 30 seconds according to MSDN:
Background tasks are limited to 30 seconds of wall-clock usage.
Your background task receives the cancel notification at 25, then it has 5 seconds to finish its job and call the deferal.Complete method. If you refuse to cancel the code running in Run
method, your task will be terminated after 5 seconds.
So I think in your case, you receive the cancellation notification but your code in the run method keeps running and reaches the finally
in less than 5 seconds, and your task completes successfully without being terminated.
Note that canceling the token source does not necessarily cancel the code in the run method immediately. Your code may be at a point where cancelling the token has no immediate effect.
Upvotes: 2