Using the below references, I attempted to make a background task in a UWP app:
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-a-background-task-on-a-timer-
https://www.youtube.com/watch?v=H18HrUin46I
Everything works as shown in the YouTube video when forcing the background task to run in debug mode, but the debug/release version on the app will not kick off the 15 minute background task on it's own. Here's the code:
MainPage.xaml.cs
using TimerBG;
bool taskRegistered = false;
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == nameof(BG))
{
task.Value.Unregister(true);
}
}
if(!taskRegistered)
{
Setup();
}
public async static void Setup()
{
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
var builder = new BackgroundTaskBuilder();
builder.Name = nameof(BG);
builder.TaskEntryPoint = typeof(BG).ToString();
TimeTrigger trig = new TimeTrigger(15, false);
builder.SetTrigger(trig);
SystemCondition userCondition = new SystemCondition(SystemConditionType.UserNotPresent);
builder.AddCondition(userCondition);
builder.CancelOnConditionLoss = false;
builder.Register();
}
BG.cs
using Windows.ApplicationModel.Background;
using Windows.Storage;
namespace TimerBG
{
public sealed class BG : IBackgroundTask
{
BackgroundTaskDeferral _deferral;
public async void Run(IBackgroundTaskInstance taskInstance)
{
_deferral = taskInstance.GetDeferral();
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await storageFolder.GetFileAsync("sample.txt");
await FileIO.WriteTextAsync(sampleFile, DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString());
_deferral.Complete();
}
}
}
The package manifest background tasks property is set to "Timer" with the Entry Point as "TimerBG.BG".
Found the solution after reading the article:
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/debug-a-background-task
Background tasks and Visual Studio package deployment
If an app that uses background tasks is deployed using Visual Studio, and the version (major and/or minor) specified in Manifest Designer is then updated, subsequently re-deploying the app with Visual Studio may cause the app’s background tasks to stall. This can be remedied as follows:
If you already deployed the app using Visual Studio and its background tasks are now stalled, reboot or log off/log in to get the app’s background tasks working again.
Related
I am using a UWP project with a background task that is triggered by the internet being available. Once triggered, a toast notification is displayed.
The problem is that the background task seems to only run once after launching the UWP application. it even works after closing the application and restarting my computer as long as I haven't triggered it before doing so, but only if it is untriggered before restarting.
What am I doing wrong? am I missing something or misusing the background task?
For clarification, I want it to send a notification every time the internet is connected. The background task should run independent of the main application.
Below is the code for the background task:
namespace AppService
{
public sealed class testNoteUpdaterTask : IBackgroundTask
{
BackgroundTaskDeferral _deferral; // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation
public void Run(IBackgroundTaskInstance taskInstance)
{
// Get a deferral so that the service isn't terminated.
_deferral = taskInstance.GetDeferral();
// Construct the content
new ToastContentBuilder()
.AddArgument("action", "testNote")
.AddArgument("conversationId", 9813)
.AddText("Program update avaliable for testNote")
// Buttons
.AddButton(new ToastButton()
.SetContent("testNote stuff")
.AddArgument("action", "open")
.SetBackgroundActivation())
.Show();
_deferral.Complete();
}
}
}
And here is the code which I use to register the background task inside the main UWP application:
public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint, string taskName, IBackgroundTrigger trigger, IBackgroundCondition condition = null)
{
// Check for existing registrations of this background task.
foreach (var cur in BackgroundTaskRegistration.AllTasks) {
if (cur.Value.Name == taskName){
// The task is already registered.
return (BackgroundTaskRegistration)(cur.Value);
}
}
// Register the background task.
var builder = new BackgroundTaskBuilder();
builder.Name = taskName;
builder.TaskEntryPoint = taskEntryPoint;
builder.SetTrigger(trigger);
if (condition != null) {
builder.AddCondition(condition);
}
BackgroundTaskRegistration task = builder.Register();
return task;
}
public MainPage()
{
this.InitializeComponent();
RegisterBackgroundTask("AppService.testNoteUpdaterTask", "testNoteUpdaterX", new SystemTrigger(SystemTriggerType.InternetAvailable, true));
}
I checked your code. It seems that when you are registering the SystemTrigger here:
new SystemTrigger(SystemTriggerType.InternetAvailable, true)
You are setting the oneShot parameter as true, which means the system event trigger will be used only once. Please set this value to false if you want the system event trigger to be used every time the event occurs.
More information here:SystemTrigger(SystemTriggerType, Boolean) Constructor.
Please use the following code:
new SystemTrigger(SystemTriggerType.InternetAvailable, false)
You could also take a look at the official background task sample here:
BackgroundTask Sample line 166.
I'm working on the "feature" the push notification trigger available in Windows phone 8.1. My goal is to make this work with a Windows phone Silverlight 8.1 project. As far as I know, it should work based on my reading.
After 2 days, I'm totally stuck. No matter what i'm trying. When I send a raw notification to my app, my app is canceled and I'm back to the windows menu.
The output :
The program '[1852] BACKGROUNDTASKHOST.EXE' has exited with code 1 (0x1).
The program '[2712] AgHost.exe' has exited with code 1 (0x1).
State :
The app receives the notification. It trigger OnPushNotificationReceived. (After this event, the app is canceled)
The Push Notification task is declared and the entry point is defined to Push.Notification.
I create a Windows Runtime Component for Windows phone 8.1 in order to run the background task.
The background task is well registered.
private async void RegisterBackgroundTask()
{
UnregisterBackgroundTask(taskName);
BackgroundAccessStatus backgroundStatus = await BackgroundExecutionManager.RequestAccessAsync();
if (backgroundStatus != BackgroundAccessStatus.Denied && backgroundStatus != BackgroundAccessStatus.Unspecified)
{
try
{
BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = taskName;
PushNotificationTrigger trigger = new PushNotificationTrigger();
taskBuilder.SetTrigger(trigger);
taskBuilder.TaskEntryPoint = "Push.Notification";
BackgroundTaskRegistration task = taskBuilder.Register();
}
catch (Exception ex)
{ }
}
}
The background task :
public sealed class Notification
{
public void Run(IBackgroundTaskInstance taskInstance)
{
Debug.WriteLine("Background starting...");
Debug.WriteLine("Background completed!");
}
}
I have no clue about what I'm doing wrong.
Is there someone who make it works ? (Not in theory)
For information, I have 2 warnings that worrying me :
I have a mismatch in the process architecture in my 2 projects. My windows phone project use "Any CPU" (can"t change that). My windows runetime component project use "ARM". If I use "Any CPU" wor my WinRT, i got an errror :
/platform:anycpu32bitpreferred can only be used with /t:exe, /t:winexe and /t:appcontainerexe
There is a conflict on a dependent assembly of the 2 projects. Seems to be
Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file:
Thanks in advance
I did finally make it works.
There was an error in my initial code I forgot to implement IBackgroundTask :
public sealed class Notification : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
Debug.WriteLine("Background starting...");
Debug.WriteLine("Background completed!");
}
}
And I had to make my Task async...
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
// perform your async task and then call deferral complete
await Test();
deferral.Complete();
}
private static async Task Test()
{
//TODO with an await
}
Hope this'll help someone.
I am implementing a background task for my Windows Store Application (Win 8.1 App). I have written a very simple test class, registered it, prompted for access, but when I choose to debug the task from the debug toolbar, nothing happens. I have also waited 15 minutes multiple times today and it does not output anything. Yet, it shows (from the code perspective) that the Task is registered and I am not getting any exceptions generated.
The Background Task:
public sealed class BGFunMessage : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
Debug.WriteLine("Background " + taskInstance.Task.Name + " Starting...");
}
}
The Register Class:
public class RegisterWorkers
{
public static async void Run()
{
var taskRegistered = false;
var taskName = "BGFunMessage";
BackgroundTaskRegistration bTask = null;
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == taskName)
{
//taskRegistered = true;
bTask = (BackgroundTaskRegistration)(task.Value);
bTask.Unregister(true);
break;
}
}
if (!taskRegistered)
{
string entryPoint = typeof(BGFunMessage).FullName;
bTask = RegisterBackgroundTask(entryPoint, taskName);
}
}
public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint, string name)
{
var builder = new BackgroundTaskBuilder();
builder.Name = name;
builder.TaskEntryPoint = taskEntryPoint;
builder.SetTrigger(new TimeTrigger(15, false));
BackgroundTaskRegistration task = null;
try
{
task = builder.Register();
}
catch (Exception ex)
{
LiveLog.WriteException(ex, LogType.WARNING);
}
return task;
}
}
How I call it from a page in my app:
RegisterWorkers.Run();
I have tried following multiple tutorials, that all mostly say the same thing. I am also using the MSDN Samples downloaded from GitHub and I don't see anything on the surface that makes their code any different from mine (apart from that their Register method returns a Task<>). I am able to debug the Sample project background tasks, but not my own. Is there something I am doing incorrectly here? Thanks.
After many hours of troubleshooting, I have found the solution to my problem. I am unsure of why this must be the case, but it works. Originally (unspecified above), I had the Background Task in the same project as my app. The ONLY difference I could find across the board was that everywhere I seen, the background tasks were in a WINDOWS RUNTIME COMPONENT project. I pulled my code out and into its own project, and referenced the .DLL and now it all works fine.
I should note however, if anyone ever needs this fix--that now I no longer have access to any of my data or SyncContext from Azure Mobile Services as it currently stands. I have no idea what I am going to have to re-architect to make it work now, but the issue above is now resolved.
I will assume, that you should always have a Shared Code library project that your main app project should reference, that way my Background Task can also reference the shared project and I can still have access to my models and other data.
I Need To Run Some Functions In Background In My Windows Phone 8.1 App.
I Have Created A Different Project For Background Tasks In My Solutions.
But Application Is Crashing When I Try To Register Following BG Task.
Here is My Code To Register Task`
private async void TasksRegistration()
{
var taskRegistered = false;
var TaskName = "FirstBG";
// Checking If Task Is Already Registered..
foreach (var task in Windows.ApplicationModel.Background.BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
return;
}
}
var builder = new BackgroundTaskBuilder();
builder.Name = TaskName;
builder.TaskEntryPoint = "BackGroundTask.FirstBG";
builder.SetTrigger(new TimeTrigger(15, true));
await BackgroundExecutionManager.RequestAccessAsync();
BackgroundTaskRegistration Task = builder.Register();
}
Application Crashed On Last Line When I Try Register This Task.
I Have Written XML Code In .Appx Manifest.
I had the exact same problem, it is most likely do to the fact that your Background Task Project is not set as a Windows Runtime Component.
Make sure the Output Type: is set to a Windows Runtime Component
Im having a issue with the Background Tasks in WP8.1
I have created a background task as a windows runtime component following this tutorial :
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977055.aspx
The problem is, i can't get my background task to run. It runs onNetworkChange. When i can to flight mode and back it is not firing. When i go to lifecycle events in the Debug Location toolbar it says No Background tasks. I have debugged the code that registers the background task and it is getting registered. I am also getting 'This breakpoint will not currently be hit. No symbols have been loaded for this document' which i think is causing the problem.
I have tried
- deleting the bin and obj folder and rebuilding.
- cleaning the project.
- trying to build the project from scratch.
- turning Just my code option off.
- tried doing the same thing on another machine, still nothing.
My code for registering
var taskRegistered = false;
var exampleTaskName = "UploadTask";
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}
if (!taskRegistered)
{
var builder = new BackgroundTaskBuilder();
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "Tasks.Upload";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.NetworkStateChange, false));
BackgroundTaskRegistration task = builder.Register();
}
package manifest file is as follows
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.Upload">
<BackgroundTasks>
<Task Type="systemEvent" />
<m2:Task Type="deviceUse" />
</BackgroundTasks>
</Extension>
</Extensions>
My task looks like this :
namespace Tasks
{
public sealed class Upload : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
Debug.WriteLine("Am i even getting here?");
}
}
}
Can anyone help as i've spent far too long getting this to work. Thanks
As I've tried your code, there is a problem with this specific SystemTriggerType.NetworkStateChange - indeed I also don't see the registered BackgroundTask in Lifecycle Events dropdown. But if I only change the SystemTriggerType for example to SystemTriggerType.TimeZoneChange then I'm able to see it.
Here is the code modified a little:
await BackgroundExecutionManager.RequestAccessAsync();
if (!taskRegistered)
{
Debug.WriteLine("Registering task inside");
var builder = new BackgroundTaskBuilder();
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "Tasks.Upload";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
BackgroundTaskRegistration task = builder.Register();
await new MessageDialog("Task registered!").ShowAsync();
}
I'm not sure why with the original code the BackgroundTask is not visible in VS, though it is being registered - it's in BackgroundTaskRegistration.AllTasks - in this case maybe try to debug with different SystemTriggerType and swich to desired one with release version.
I've also tested if the BackgroundTask with the problematic SystemTriggerType.NetworkStateChange works - and indeed - it is working. I've modified your BackgroundTask a little to send a toast message when NetworkState changes. After registering the task, when I turn the WiFi on/off, I get a toast messgae. The code for the task:
public sealed class Upload : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
Debug.WriteLine("Hello Pat");
ToastTemplateType toastTemplate = ToastTemplateType.ToastText02;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
XmlNodeList textElements = toastXml.GetElementsByTagName("text");
textElements[0].AppendChild(toastXml.CreateTextNode("Upload Task - Yeah"));
textElements[1].AppendChild(toastXml.CreateTextNode("I'm message from your Upload task!"));
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastXml));
}
}
The complete example you can download here.