My background task takes a long time to complete, and the OS is just killing it. I'm trying to sync my contacts online, here's what I'm doing:
Get all contacts from phonebook (takes ~1 second)
Upload them to a server (~2 seconds)
Retrieve all contacts from server (~2-3 seconds)
Delete all contacts from ContactStore(ContactStore.DeleteAsync sometimes takes 1 minute to complete)
Create a ContactStore and import all contacts )(~1-2 minutes for 1000 contacts)
I have ~100 contacts and it's working well, but I wanted to test with ~1000 contacts and it doesn't complete every time. I'm using a MaintenanceTrigger, but I think it's still too much for a background task, but I need a confirmation for this. MaintenanceTrigger tasks should be allowed to do more resource intensive tasks, so why is the OS killing my background task?
Take a look at this link: https://msdn.microsoft.com/en-us/library/windows/apps/hh202942(v=vs.105).aspx
Resource intensive tasks are constrained to a duration of 10 minutes.
The following constraints must be met before the task is started. If the device stop fulfilling these constraints the agent is terminated immediately.
External power required
Non-cellular connection required
Minimum battery power
Device screen lock required
No active phone call
Cannot change network to cellular
Besides this there are also a memory cap of respectively 11mb and 20mb for low/high end devices.
From your description above the most likely scenario IMO is the memory cap being hit. Maybe this post can help you look into the memory usage of your background task: How to get memory available or used in C#
Key changes to memory limits starting in Windows Phone 8.1 include (found here):
All Windows Phone 8 foreground apps are treated the same. We no longer have different memory caps for XNA, native or Silverlight apps.
Windows Phone 8.1 apps (including both Silverlight 8.1 and Windows Runtime) apps do have slightly higher caps than Windows Phone 8 apps.
Memory caps for all app types, including Continuous Background Execution (CBE), scale up with increased memory.
There is no longer a "default" and "higher" cap - there is only the default cap.
The ID_FUNCCAP_EXTEND_MEM manifest entry is ignored for all apps running on Windows Phone 8.1.
The ID_REQ_MEMORY_300 manifest entry is still valid, but you should really make your app run on all devices.
The new equivalent of ID_REQ_MEMORY_300 is below. This entry should be added to the AppX manifest (not to the WMAppManifest).
Finally, my task got canceled with the reason ExecutionTimeExceeded, so this is the problem. It seems that trying to import ~1000 contacts in the ContactStore takes ~12 minutes, which is too long for a background task. I'll have to make the user to open the app and do the import. Thank you for your help.
erm... may be silly but...
"Background tasks that use a maintenance trigger run only when the system is connected to AC power." Taken from MSDN
Could it be plugged into the mains when it works?, and not plugged in when it doesn't work?
EDIT: Are you considering how busy the phone is when you try to 'sync' contacts? Are you forcing the app to allways run in the background via Battery Saver?
You could do something like this to see how busy your phone is... or it could be the battery saver halting your app if download size etc limits are reached...
Taken from here...
var result = await BackgroundExecutionManager.RequestAccessAsync();
if (result == BackgroundAccessStatus.Denied)
{
// Handle this if it is important for your app.
}
"If the result is denied the phone thinks it has too much background task active. In that case you can prompt your users to go the Battery saver application and force allow your app to run in the background even if the phone donĀ“t want to..."
Related
I'm trying to convert an Android app to Windows 10 UWP. On android its easy: when boot completed, app service is started. It connects to controller over internet, fetches system state and all data (temp sensors, pumps, valves, etc) and keeps everything in memory. Foreground app can get data as soon as service gets them and display values, charts realtime. After closing foreground app, service keeps working, I still have all system state and I can play alarm sound if needed.
Is it possible to do [almost] same functionality on Windows 10 uwp?
I cannot find a way to start service with windows. Service started with foreground app is stopped when foreground app is closed. SocketBackgroundTask keeps connection perfect, but system state is lost with service.
Should I save system state to file and analyze all data after each renew? Data flow varies from once in 10 minutes to ~10 per second.
Or should I forget Windows 10 as limited platform?
I am designing a similar piece of sensor control software, and I have found UWP/Win10 to be limiting. We ultimately resorted to using Assigned Access to keep the app permanently in the foreground.
Assigned Access
Assigned access assigns an app to an account. So when Mr. Bob logs in, the app starts full-screen, and it cannot be closed, and if it crashes, it is restarted.
Note that the only way to access other parts of the system is to hit ALT-CTRL-DEL and log in as a different user. That might be bad for some, but if you have critical process monitoring going on, then it's probably a good thing that the user can't mess about with the system or quit the app.
It's also quite simple to implement, you only need to add a declaration to the app manifest, and you need Win10 Pro or Higher.
Windows IoT
You could also look at Windows 10 IoT, when you deploy an app to it, it does pretty much the same thing. However the range of hardware is quite limited, and many of them aren't fully functional yet - RPi suffers from SDcards being inherently unreliable, and lack of graphics acceleration. Dragonboard lacks driver support for resolutions other than 720p, etc. https://developer.qualcomm.com/forum/qdn-forums/hardware/iot-development-platform/29652
Extended Execution
In addition we have experimented with using extended execution, which lets the app run in minimised state, potentially indefinitely. I have mixed feelings about it. Although the app will keep running most of the time, but if the OS is struggling for resources, the app will get suspended and won't be restarted until the user switches back to it.
According of this link Microsoft Increases Memory Limit For Apps In Windows Phone 8.1 in my 2GB device available for background task 40MB memory. But when I trigger my background task with breakpoints in a first string in Run method I see in Windows Phone Developer Power Tools (8.1) for my task Private Bytes is 30.73MB Working Set 31.27MB.
MemoryManager show me 35 Mb in Run method.
Is it mean I can use only 40-30=10MB for my needs in background
task?
Is it possible to change 30MB (switch off some requirements
in manifest)?
How it work for 512MB devices where available only
16MB memory for background task?
P.S. After reset of the phone and reinstall application I see only 2 MB at the same string...
Windows Phone platform offers BackgroundTasks infrastructure. I can register my task like that:
builder.TaskEntryPoint = TaskName;
var trigger = new TimeTrigger(15, false);
builder.SetTrigger(trigger);
builder.Register();
The problem is, that TimeTrigger min interval is ~15 minutes, which is pretty large for my application. I need to have task which runs every 1-2 minutes in the background. Is it possible on Windows Phone?
It is not possible to have BackgroundTasks that run on a minute interval basis.
As you said already the minimum interval is 15 minute.
This is an OS limitation to prevent developers to build battery draining applications.
You always have some workarounds, like having a PushNotificationTrigger, and manage to send a push notification to your device every minute. (I guess some people manage to do so with the ScheduledToastNotification), but i wouldn't recomend it.
AFAIK with the official API - it's not possible to run TimeTrigger so often. Note that on WIndows Phone, the interval is even larger (MSDN):
Windows has a built-in timer that runs background tasks in 15-minute intervals. Note that on Windows Phone, the interval is 30 minutes.
I doubt it will be possible, due to battery consuption/restrictions. Maybe you can leave your app in the foreground and disable lockscreen (by using DisplayRequest).
Also you may try to run a timer along with obtaining deferal in your BackgroundTask. I've not tried that, for sure there will be many problems (CPU limit, memory and other restrictions), I'm not sure if that is not against certification requirements and of course it doesn't guarantee that your BackgroundTask wouldn't be terminated by OS.
For my app I need to be able to let the user specify a given time and let my app run a background task at that specific time.
I understand that with wp8.1 a timetrigger background task can only run every 15 minutes. Is there anything I can do to ensure my app will run the task if the time has gone 10 minutes over the user's specified time?
For what I understand tasks are only executed in intervals multiple of 15 minutes in Windows 8.1 and 30 minutes in Windows Phone 8.1. Have a look here: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh977059.aspx
I can not add a comment, that's why I share my experiences as an answer.
We had a similar problem in an application - we target the Windows Store 8.1 platform but our experiences can be relevant for you as the app cycles in the two platform are converged (http://msdn.microsoft.com/en-us/library/windows/apps/dn632424.aspx).
In our app we have to monitor streams and collect information. This logic has to be executed per minute what is not supported, as mentioned. That's why we use a simple Task with a CancellationTokenSource, and we start/stop the task in the app cycle-related events (Suspending, Resuming). This "solution" is not acceptable if the execution of the background logic is required when the app is suspended, too, but in our case this was not required.
I want to potentially update the tile of my WP8 app periodically - no more frequently than every hour or two. However, I don't want my app to have to be running for this background task to take place (will query a WAMS and, based on the returned results, update the WP8 app's tile).
Is this possible, or do background tasks (I found this tutorial on how to create one:
http://thesociablegeek.com/windows-8/livetiles/modifying-live-tiles-in-a-background-process/) require that the app that hosts them be running?
IOW, what I basically need is similar to a Windows Service, that his hosted by the OS, not a/my particular app.
Here's a guide how to use so called Background Agents in Windows Phone 7 or 8:
Background agents for Windows Phone
Basically you can schedule simple task to be executed every 30 minutes, even the main application is not running. There are system requirements on these tasks like memory cap constraint 6 MB for WP7 and 11 MB for WP8 tasks, run time of each task 25 seconds, and limited available APIs.
I would recommend that you code your tile update logic as a periodic task and then configure it to run in background. this way, you don't have to maintain your app running in background.
Hope this helps.