Mango fast app switching & heavy processing crash - c#

I have a WP7 app that sometimes has to make a long (5-25 sec) processing.
With Mango, when the app is set to Dormant state while it was processing (ex: the user presses the Windows button or locks the screen), when the user comes back, the app crashes.
I tried on the emulator and on my device, same behavior.
If I reproduce it in debug mode on Visual Studio, it doesn't crash so it's hard to find what is really happening.
To reproduce it, start a new Windows Phone project, add a button on MainPage.xaml & add an event handler on the click event that executes an infinite loop:
while (true)
{
System.Threading.Thread.Sleep(100);
}
My question is: What is really happening? Why does it crash? Isn't fast app switching supposed to just pause the app process and resume it?
EDIT:
Another thing I noticed is that when running the heavy process, the deactivated & activated events do not seem to be raised when I get out/in the app.

Found the answer on the official Windows Phone forum (link). Here it is:
Why it crashes:
From the time the app is deactivated, it has exactly ten seconds to
finish up what it is doing. If the code takes more than ten seconds,
the OS will terminate the app.
Why the deactivated & activated events are not raised when I get out/in the app:
If the process is blocking the UI thread this also blocks the message
dispatch loop so I suspect that this is the reason why your app never
gets a chance to detect and handle the events.

Your problem is simple. WP7 cant really put your threads in a dormant state when you are under heavy processing in this fast time and will save a corrupt state. This state will crash when its reactivated.
It works in the debugger because the debugger makes everything slower and then WP7 has more time.
From Documentation:
When the user navigates forward, away from an application, after the Deactivated event is raised, the operating system will attempt to put the application into a dormant state. In this state, all of the application’s threads are stopped and no processing takes place, but the application remains intact in memory. If the application is reactivated from this state, the application does not need to re-create any state, because it has been preserved.
Source: http://msdn.microsoft.com/en-us/library/ff817008(v=vs.92).aspx

Related

Windows Hello Unlock Companion Device Framework Background Task Not Being Triggered

I have been testing a C# Companion Device Framework application, which unlocks my laptop fine for the most part. However, it doesn't seem to work after I leave my laptop locked for a while.
I used the code from the CDF GitHub sample to fire a toast notification when the background task for my UWP companion app is triggered.
This shows me that there is never an issue when I attempt an unlock shortly after locking the machine. When I lock my machine, I immediately see the toast notification indicating that the background task was triggered. However, if I lock my laptop and leave it for a few minutes, it doesn't appear that the background task gets triggered again, even though I wake up the screen and press buttons.
I want my CDF app to always be able to unlock my machine. What did I do wrong? Hopefully I don't need it, but is there a workaround like registering a second trigger for the background task to a custom service?
UPDATE: It appears this occurs only if the computer does not go to sleep, which may occur in the case that someone has either set a long time before sleep or has sleep off completely (as I did previously). If the laptop does go to sleep, and has to be woken up with a trackpad click, then the background task seems to fire.
The problem is, Windows UWP stops to fire the event WaitForUserConfirmation after awhile.
At present, we have 2 possible solutions:
user hits the keyboard and the background task catches the event CollectingCredential and invokes the companion device authentication
once the background task is running, it loops until the event CredentialAuthenticated, and it runs the companion device authentication periodically.

Application closed event in windows store app?

I want to get event when windows store app is closing or page is closing same way as we get "Closing" event in Desktop application.
Can anybody suggest me?
Try this:- https://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx
refer:- How to save data on Windows Store App Close?
If you look at the very first figure, you can see that there are only 3 events related to application lifecycle:
Activated - Raised when program first starts
Suspended - Raised when program is suspended (i.e. the user returns to the Start Screen or another app)
Resuming - Raised when the program is awakened from its suspended state.
The fourth transition - the one to the "Not Running" state - has no such notification event. The reason is: you don't really know when the app will fully close. Nor should you - Microsoft wants you to perform all of your state-saving logic in the transition from "Running" to "Suspended." In this way, they can free up resources when they deem necessary.
Even if the user forces the program to terminate (by right-clicking it and selecting "Close" from the task menu), you will enter the "Suspended" state for exactly 10 seconds before the program is terminated. So you can rest easy that your state-saving logic will always be executed.

Preventing the app to terminate?

I'm working with background tasks.
If I press the home button once the app will call DidEnterBackground and I can run anything here - Ok
If I press the home button twice and swipe the application out of the screen, finalizing it, WillTerminate will be called and after that, the app DIED, I can't do anything more.
On the Android I can do it and keep the app running, without show it on the android's app switcher.
There's a way to do it?
And how I re-open the app every time I kill the app (Every time WillTerminate is called).
You cannot avoid the kill by the user. Apple philosophy is that the user is the "commander-in-chief" and he can decide to kill your app when he wants (and the kill must be real, no hidden processes).
All background tasks of the app will terminate with it and you cannot reverse the user decision (i.e. restarting automatically).
I don't see simple solution for your problem. The only thing that I can think is to put a big alert message to the user, when a specific task begins, saying:
"don't kill this app from the switcher while this operation is running ..."
or, save the state of the background process and restart it at the next run of the app.

App Resuming event not firing when the app is resumed in WP 8.1 store app

My WP 8.1 store app behaves very strangely. App Resuming event fires as expected when I quickly navigate away and then come back. But If I keep the app in background for some time and when comes back, the app fires the Constructor and OnNavigatedTo events instead of the Resuming event and has the black "Resuming..." screen for a couple of seconds(about 4 seconds).This is an app with a BackgroundAudio task. Even the sample BackgroundAudio app from MS behaves like this. Anyone knows what's wrong here?
I'm in the process of building a WP 8.1 app which uses a background audio task as well. Everything you explained happens to me also.
If you see "Resuming..." for a few seconds, then it probably means your app was terminated by the OS after being suspended first. In this case, the Resuming event won't fire because your app was completely killed and must start again. "Resuming" usually means when a suspended (not terminated) app resumes execution.
When your app is terminated and then "resumed" from the app switcher, your Application.OnLaunched() method override will be invoked with e.PreviousExecutionState == ApplicationExecutionState.Terminated. In this method, you should check if the previous execution state was Terminated, and if so, restore the app to the state it was in prior to suspension. This gives the illusion to the user that the app was never terminated and they can resume what they were doing at the time.
If you create a new Pivot App Windows Phone 8.1 project (for example), you'll see that the application lifecycle events are taken care of correctly in App.xaml.cs.
App Resuming event fires as expected when I quickly navigate away and then come back.
This is correct behavior. It takes a few seconds once the app has been backgrounded before it is suspended by the OS, so if you resume the app before the OS has suspended it, then it will simply resume from memory.
I'm not sure why background audio apps are more susceptible to termination. I even find that the Xbox Music app behaves similarly. Hopefully in the next version of Windows Phone, this issue will be addressed.
FYI here's a diagram of the application lifecycle from MSDN (I recommend you read this page for more information about the application lifecycle):
"Resuming" only occurs from the suspended to running states.
Whenever the app resumes from the background. there are two states it can be in:
Suspended: it resumes successfully, navigating directly to OnNavigatedTo; the constructor will not be called
Terminated: the app will not start from the previous state of the page you left, but instead, it will load that page anew; at this point of time you need to have saved the state while the app was suspending, so as to restore it now

How do you prevent BackgroundTask from being cancelled if it's appears Idle (but is not due to very small regular workload)?

I have an app that uses a timer similar to this example code:
Sample Code for BackgroundTasks
Specifically the part with a timer.
So my code runs as intended when I launch the app in debugger. Every minute the event fires and I log to a text file (and do a tile notification).
My problem is when I run it normally without debugging, it runs four times (sometimes five) and then nothing. Looking at the processes running I can see the backgroundtask and then its gone. I've got logging in the OnCancelled even and it's never called.
I even tried creating a deconstructor for the background task to see if that is called (and put some logging there) and it doesn't seem to be.
Also no exceptions seem to be thrown, at least they are not logged and I have a try catch around the timer.
Suggestions on how I can track down why the background task seems to be squashed (I thought if the system wants them closed, it cancels them?)
Update: I ran the app normally without debugger attached, and when I saw the backgroundtask process appear, I attached my debugger to it. It ran for 8 minutes (where the log was showing previous runs stopped after four). When I detached the debugger at that point it ran a further four times (once per minute) and then the process disappeared.
Update: Ok I think I have worked out what is happening, but not why.
http://msdn.microsoft.com/en-au/library/windows/apps/hh974425.aspx
When you are not debugging, Windows Process Lifetime Management (PLM) controls the execution state of your app—starting, suspending, resuming, and terminating the app in response to user actions and the state of the device. When you are debugging, Windows disables these activation events.
So I guess this may change my question to how do I find out why Backgroundtask is being suspended when it still has work to do?
Update: Worked out my issue, I was attaching Canceled handler to a field variable (which was being assigned in Run method. Attaching Canceled handler directly to the instance passed into Run method made the Cancel call work. I didn't think that would make a difference as its a reference tot he same thing. Anyway, Cancel reason is "IdleTask". Increasing the frequency of the timer seems to make the background task not get cancelled.
So question is now How much is enough work to not be cancelled due to being Idle? Can you check for this and adjust? Can you override the check? I don't want to just do work for the sake of not appearing idle. That's going to waste battery life!
I have a similar problem (and found for my app an acceptable workaround).
But your question is interresting and still unanswered:
Although with a BackgroundTaskDeferral sometimes the system assume that the task is idle and cancel the task:
BackgroundTaskDeferral defferal = taskInstance.GetDeferral();
while (Task runtime less than 14 minutes and 35 seconds)
{
... do something
// wait 20 seconds
new System.Threading.ManualResetEvent(false).WaitOne(20000);
}
defferal.Complete();
The real task is a little bit more complicated:).
I also don't want to just do work for the sake of not appearing idle.

Categories

Resources