Do we have this already? The process and syntax of dealing with background tasks can be lengthy and unclear. I have had written a helper class to deal with this before (register/unregister, check if task exists... etc).
Can be usefull indeed imo. Also providing the valid namespace & class name have always been misleading for many developers when it comes to the background tasks. Maybe checkin for that using some of the reflection goodies?
I'll look into the reflection part. Probably having them type in the class name of the background task, and use reflection to pull the full string path later on. We can leverage Intellisense when they type in the class name too.
What kind of API this helper could provide?
To register a background task, it needs the name, task entry point (which are string, and easy to confuse and mess up the correct string). Also the Triggers and Condition, which could be simplified.
I was thinking something along the line of having multiple high level methods like RegisterTimedBackgroundTask(Type backgroundTaskClass, TimeSpan delay, Condition optionalCondition = null) for registering a background task that use TimeTrigger to invoke the task.
@Code-ScottLe do you envisage something like this? https://github.com/ScottIsAFool/EchoWallpaper/blob/master/EchoWallpaper.Windows.Shared/Services/BackgroundTaskService.cs
@ScottIsAFool Some what, but probably going to be closer to this:
https://github.com/Code-ScottLe/USCISTracker/blob/master/USCISTracker/USCISTracker.Services/BackgroundServices/BackgroundService.cs
The problem with registering the task is the name of the background task and the task entry point (which is the namespace of the class) are in string form. If we can solve this my letting user type in the Type of the class alone, and use reflection to resolve the rest of the info, it will probably help out a lot.
Something like RegisterTimedBackgroundTask(typeof(BackgroundTask1), new TimeSpan(0,0,5)); looks a lot cleaner than the whole constant string that you and me both did with our application.
@Code-ScottLe Yes, could be helpful to have a BackgroundTaskService with list of current tasks and method to (un)register tasks.
Let's try and see how it looks like:)
I'll give it a go. I'll ping back when it is ready for pull request.
@Code-ScottLe Another implementation, if you need inspiration https://github.com/Odonno/Modern-Gitter/blob/master/Gitter/Gitter/Gitter.Shared/Services/Concrete/BackgroundTaskService.cs
@Code-ScottLe What is your progress ?
@Odonno hey, sorry. I was incredibly busy with stuff last week. I have done a few functions but had to reconsider the naming and the required/optional parameters for all the functions. I will post the example when I have time.
Very sorry for the long delay, a few things happened and I wasn't really available in the last 2 weeks to do anything. Here is the sample class that I have written as an example of how this could be. Any feedback on this would be great.
This is an example on how this would look like from the user perspective:
bool isServicingHandled = BackgroundTasksService.IsBackgroundTaskRegistered(typeof(ServiceCompletedBackgroundTask));
if(isServicingHandled == false)
{
BackgroundTasksService.RegisterSystemBackgroundTaskAsync(typeof(ServiceCompletedBackgroundTask),SystemTriggerType.ServicingComplete).Wait();
}
Edit 1: Mistakenly closed this. Re-opened.
Edit 2: The .Wait() was necessarily just in this case because the piece of code was inside the non async OnLaunched() of App.xaml.cs
I'm a fan of the "IsBackgroundTaskRegistered" method, that's something I always have to do which is slightly annoying.
I'm not sure creating methods for registering system background tasks vs time trigger/etc is the right approach though, that's just a lot of duplication of existing methods in the platform. And I've never found those platform API's to be annoying.
Anyways, for your IsBackgroundTaskRegistered, that code could be more efficient by using "Any" rather than checking the count...
return BackgroundTaskRegistration.AllTasks.Any(t => t.Value.Name == backgroundTaskType.Name);
By using "Any", it'll stop iterating once it finds a match, rather than with Count, it'll have to iterate the whole thing.
@anbare the thought process behind this, was to provide some helper methods to quickly register a background task that will be fired when something happens (times, sys event are a few popular ones...). I thought this was a good idea since i stumbled upon this myself when i learned about background task (how to have a background task that run in x minutes? Oh , there it is, a time trigger... and that took me half an hour, ugh.)
The core of this API is still the RegisterAsync method though, because all of those helpers are just shortcuts to this method. This will allow people to still use this API without having to use those helpers.
I'll change the LINQ on the IsBackgroundTaskRegistered upon your feedback :)
Good point about it being difficult to discover how to register background tasks like time triggers, it'd be interesting to know if others have ran into the same problem. What I did when I first started using WinRT background tasks was I looked up the documentation for how to use background tasks, and then quickly learned the whole pattern of "triggers". So I personally didn't struggle with discovering how to use their API's, but if others are commonly struggling with it, then it's definitely something we ought to help improve with your additional methods!
Anyways, that's just my two cents as a fellow UWP app dev :)
Also - we should ensure that we support Single Process Model. Essentially, you just need to provide an option in the Register method to say "Use single process model?", and if so, you do NOT set a TaskEntryPoint on the BackgroundTaskBuilder. And then the background task gets activated in your App.xaml.cs file, in the same process as your foreground app, and it's sooooooo much better than having to have a separate WinRT library, and it's super awesome :) that was added in the Anniversary Update, so only works on 14393.
Love the idea of support SPM here! This gives the tool far more interest to me
Good catch on that, I haven't had time to actually touch SPM on the Anniversary Update yet, but have heard good things about it. I'll update the Register method accordingly, probably an overload.
Are there any attributes that we can use to hide the SPM version of Register away from users who are not targeting the Anniversary Update?
I don't know of any attributes that we could use - additionally, someone could be targeting 14393 but still using 10240 as min version, so in that case they need to check at runtime what API contract their on, and diverge their code.
I would just make the summary comments on the overload clearly state "New in 14393" or something similar, so that when devs see the overload, they're aware that "Hey this is new, I need to do something special if I'm still supporting older systems"
Maybe someone else has better ideas though!
I guess a PR is required now :) At least to see implications and how one can use the code
@deltakosh Alright, I'll make one tonight. I was kinda waiting on your word if this will make it :)
Most helpful comment
Good point about it being difficult to discover how to register background tasks like time triggers, it'd be interesting to know if others have ran into the same problem. What I did when I first started using WinRT background tasks was I looked up the documentation for how to use background tasks, and then quickly learned the whole pattern of "triggers". So I personally didn't struggle with discovering how to use their API's, but if others are commonly struggling with it, then it's definitely something we ought to help improve with your additional methods!
Anyways, that's just my two cents as a fellow UWP app dev :)
Also - we should ensure that we support Single Process Model. Essentially, you just need to provide an option in the Register method to say "Use single process model?", and if so, you do NOT set a TaskEntryPoint on the BackgroundTaskBuilder. And then the background task gets activated in your App.xaml.cs file, in the same process as your foreground app, and it's sooooooo much better than having to have a separate WinRT library, and it's super awesome :) that was added in the Anniversary Update, so only works on 14393.