7
votes

I'm developing a WP8.1 SL app which uses background tasks (not agents!).

My task is triggered by a TimerTrigger - once every 30 minutes (which I believe is the minimum interval for Windows Phone, right?). It is doing a lot of work, and for some reason, sometimes it gets interrupted - that is, it stops in the middle of it. The way I know it's in the middle of it is because I log what's happening and the task's work is basically the same every time.

I deployed the app to my device yesterday to test a new approach, and everything was working fine - the background task was doing everything every time it was started - worked like a charm. Today my device needed a soft reset, so I did it (nothing was working, it happens from time to time since I updated to WP8.1). Since that moment, the background task gets interrupted every time, right in the middle of it, just as with the previous approach.

Any ideas what can cause this? I'm thinking it may be connected to the soft reset, because - 100% success rate before it, 0% after that.

What I've tried so far:

  • I'm logging errors, I have a try-catch around everything, I've subscribed to the UnobservedException event and to the task's Canceled event, and I'm logging the suspension count - none of these things help. There seem to be no errors, it's not suspended, and it's not canceled.

  • I'm logging the current memory usage from time to time, and it's about 16-17MB. On my device, the limit should be 30MB, so I don't think that's a problem.

  • I'm calling RequestAccessAsync wherever I can. I thought once should be enough, but since that soft-reset issue, i decided to put it in 1-2 other places to check if it's causing the issue. Well, it's not, or at least this didn't fix it.

What I'm not sure about:

  • I have no idea how to check the CPU time my task has consumed. I can't find a good/reliable way to do so. Also, I can't find any info that would explain why the task would be stopped in the middle sometimes, and other times - it would work fine.

Any ideas why my background task is sometimes stopped at the middle? I'm really having a hard time determining how to fix/improve the app and will it work at all.

Thanks.

1
Uhhh, hard question, as in WP background tasks have many limits (you are probably aware of that :). The CPU quota is only 2 seconds - maybe this? Also have you called RequestAccessAsync? Also are you transferring any data over net?Romasz
Maybe some tests: is there a difference when the phone is powered? Is there a chance you can run a stopwatch, and notify in LocalSettings the time while your task is running? Can you build a simple task and await in it more than 2 seconds and see if it was cancelled? Also I assume that you are obtaining defferal.Romasz
Hey @Romasz! :) Thanks for the suggestions. I'm aware of 3 limits - CPU (not sure how to check), memory (checked), data transfer (not used). I'm calling RequestAccessAsync often enough. The CPU constraint is for CPU time, not actual running time. When it's doing everything the task runs for 10-15seconds. Whether the phone is charging/on battery at 20%/100% does not seem to have any effect on the task's execution. And your assumption is correct - I am getting a deferral and calling the Complete method at the end (in a finally block).yasen
Few more - is your Run asynchronous? Have you tried to subscribe to Competed/Canceled events put there a method saving something in LocalSettings to indicate the problem? Is there any CPU consuming operation (I also don't know how to measure CPU)? If there is, maybe there is a chance to slow down it a little (Task.Delay(50).Wait())? Is there a chance that you share a code or simple example with the problem?Romasz
@Romasz The run itself is not async, but it calls an async method which uses a deferral as it should. I haven't tried the Completed event, the other one does not seem to be raised. It is CPU consuming, I can slow it down, but I don't know how that would help? At the moment I can't share code as the task uses several custom libraries. I'd guess its the CPU constraint that is my problem, but I don't know how to measure it and I don't understand why it was okay and then, after the soft reset it stopped working.yasen

1 Answers

13
votes

So, I think I found what my problem was.

First of all, the background task just needed a lot of CPU time, more than the limit, and that's why it was getting killed in the middle.

The reason why it was working sometimes, was because sometimes the device on which I was testing treated the app as being in debug (or with attached debugger). In this case the restriction on CPU time is removed.

So, even if I uninstall the app and rebuild it in Release and redeploy, and start it without the debugger attached, the device was NOT enforcing the constraints. That only happens, if I have started the app with the debugger at least once (or maybe the first time) after it's deployed. Restarting the device (just power off and then turn on) fixes this.

While I was testing, using the same build of an app, its background task ran for 40 MINUTES on one device, and just 3-4 seconds on another. After I restarted the first device, the background task started behaving normally (running for just a few seconds).

So, if you want to test your background task for the CPU constraint:

  1. You must be testing on a device, not on the Emulator.
  2. Uninstall the app, if it's installed.
  3. Restart the device.
  4. Deploy a Release build of the app.
  5. Run the app, so that it can register the background task, and then close it.
  6. Wait for the background task to be invoked. (You could add a trigger that can be forced, like TimeZoneChanged or UserPresent, so that you could quickly test it.)

P.S. This may not be the perfect answer, but these are my observations, and they helped me solve my problem. This by far is the best method I have found for testing the CPU time, and it's far from perfect. So, if anyone has better ideas, please share them.