I am following https://docs.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task document to create a background task which will run every 15 minutes and ping a service.
Created a Windows Runtime Component project with a public sealed class implementing IBackgroundTask
namespace PeriodicBackgroundTask
{
public sealed class FifteenMinutePeriodicTimer : IBackgroundTask
{
private static readonly FileLogWriter mWriteLogToFile = new FileLogWriter();
public FifteenMinutePeriodicTimer() { }
public void Run(IBackgroundTaskInstance taskInstance)
{
try
{
taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
mDeferral = taskInstance.GetDeferral();
mWriteLogToFile.log("Starting periodic timer at " + DateTime.Now.ToString());
// Calling method to do a Post call to a service.
mWriteLogToFile.log("Finishing periodic timer at " + DateTime.Now.ToString());
}
catch (Exception ex)
{
mWriteLogToFile.log("Fifteen Minute periodic timer failed.", ex);
}
finally
{
// Adding some buffer for async processes to finish.
Task.Delay(TimeSpan.FromSeconds(15)).Wait();
mDeferral.Complete();
}
}
private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
mWriteLogToFile.log("Fifteen minute periodic timer is canceled. {0}", reason.ToString());
}
}
}
Entry in UWP application's Package.appmanifest file
<Extension Category="windows.backgroundTasks" EntryPoint="PeriodicBackgroundTask.FifteenMinutePeriodicTimer">
<BackgroundTasks>
<Task Type="systemEvent" />
<Task Type="timer" />
</BackgroundTasks>
</Extension>
Registering Timer at the beginning of OnLaunched Method in App.xaml.cs
public async static Task RegisterBackgroundTask()
{
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (String.Equals(task.Value.Name, TASK_NAME))
{
mWriteLogToFile.log("Old version of fifteen minute periodic timer found. Unregistering it.");
BackgroundExecutionManager.RemoveAccess();
// Unregistering so that any update in Background task can be applied.
task.Value.Unregister(true);
break;
}
}
BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
if (backgroundAccessStatus == BackgroundAccessStatus.DeniedByUser ||
backgroundAccessStatus == BackgroundAccessStatus.DeniedBySystemPolicy)
{
mWriteLogToFile.log("Fifteen minute periodic timer registration failed, due to Request access status.");
return;
}
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = TASK_NAME;
builder.TaskEntryPoint = "PeriodicBackgroundTask.FifteenMinutePeriodicTimer";
builder.SetTrigger(new TimeTrigger(15, false));
builder.CancelOnConditionLoss = false;
var backgroundTask = builder.Register();
if (backgroundTask != null)
{
mWriteLogToFile.log("Fifteen minute periodic timer registration SUCCESSFUL.");
}
else
{
mWriteLogToFile.log("Fifteen minute periodic timer registration FAILED.");
}
}
After installing the app FifteenMinuteBackgroundTimer runs 5 or 6 times. Sometimes 5, sometimes 6. When I try to debug the task using Visual Studio I am able to debug it. I am not sure, why FifteenMinuteBackgroundTimer is dying after 5 runs. Can anybody please tell me how can I debug this issue?
More Info:
Windows Build: 1607
Microsoft.NETCore.UniversalWindowsPlatform: 5.1.0
Can anybody please tell me how can I debug this issue?
After you register the background task, you will find the background task show in the drop down list of Lifecycle Events toolbar. Set a break point on the background task then click the background name in the toolbar the visual studio will trigger the background task and you can debug. More details please reference Debug a background task.
why FifteenMinuteBackgroundTimer is dying after 5 runs.
If you run any asynchronous code in your background task, then your background task needs to use a deferral.It seems like you create the deferral instance but didn't get a deferral from the IBackgroundTaskInstance
. So you may need to get the deferral firstly.
public void Run(IBackgroundTaskInstance taskInstance)
{
mDeferral = taskInstance.GetDeferral();
...
mDeferral.Complete();
}
And you may not need Task.Delay(TimeSpan.FromSeconds(15)).Wait();
for adding some buffer for async processes to finish since deferral can help you do this. The background task can only run 30s in total, actually the running time may only be 25s, if you set a delay in the background task may lead it cannot complete the task and force closed.
It is very likely you are running into two policies related to power.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With