I'm on Template10.1.1.11-preview-160509 (just updated), and I finally reached a state in my app in which I need to care about suspension/resume.
I've been messing with lifecycle events inside Visual Studio, and I noticed that something isn't going as I expect.
What happens is that OnNavigatedFromAsync is called upon suspension, but hitting Resume doesn't fire OnNavigatedToAsync, meaning that I can't restore my state.
Now, I don't know if this is intended behavior or not, but if it's intended then how am I supposed to do stuff after Restore? Because I'm doing time-related things with a DispatcherTimer and I need to reset it after restoring from suspension.
Are you suspend and terminate? if you just suspend, then typically your app would stay in memory, so would just resume and continue with the current state, rather than having to restore the state. Try suspend then terminate, then restart the app to see if it restores.
Suspend and terminate works, but it's a different case from mine.
I'll try to give a better explanation: I have a running DispatcherTimer in my ViewModel, and this decreases a value which is critical for the app.
What happens is that on Suspend the timer stops to tick and on Resume it just restarts from the value that it had before suspension, meaning that the timer won't see that time has passed.
If the OnNavigatedToAsync is not called after Resume event, I can't restart the timer and this messes up a lot. On the other hand, if OnNavigatedToAsync is called even after Resume event, I can reset the timer and let it start again from the updated timestamp, so that my data won't be invalidated.
Example:
var Value = 80;
tick -> Value = Value-1; (79)
tick -> Value = Value-1; (78)
Suspend
Resume after 5 seconds
tick -> Value = Value-1; (77) <-- this should have been 72 instead!
So, basically, on Suspend the app still stays in memory but the timer stops ticking, and not having a way to reset the timer after Resume breaks my app.
I hope that the question is a little bit more clear now.
So this isn't a problem with T10. If an application is resumed from suspension without being terminated the app doesn't navigate, so that method won't be called. It is up to the app developer to cater for that scenario.
Without understanding your scenario, it is hard to know why you are using timer and a counter. Rather than having an integer count down the number of seconds, use time and act relative to that.
Of course, you could also subscribe to the application Resuming event if you have other things you need to do.
private DispatcherTimer _timer;
private DateTime _stopTime;
public MainPageViewModel()
{
if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
{
Value = "Designtime value";
}
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
_timer.Tick += _timer_Tick;
_stopTime = DateTime.Now + TimeSpan.FromSeconds(80);
_timer.Start();
}
private void _timer_Tick(object sender, object e)
{
var seconds = (_stopTime - DateTime.Now).TotalSeconds;
Value = seconds.ToString("N0");
if (seconds <= 0)
{
Value = "Out of time!";
_timer.Stop();
}
}
string _Value = "Gas";
public string Value { get { return _Value; } set { Set(ref _Value, value); } }
public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
{
if (suspensionState.Any())
{
Value = suspensionState[nameof(Value)]?.ToString();
}
App.Current.Resuming += Current_Resuming;
await Task.CompletedTask;
}
private void Current_Resuming(object sender, object e)
{
// Do other things here!!!
}
public override async Task OnNavigatedFromAsync(IDictionary<string, object> suspensionState, bool suspending)
{
if (suspending)
{
suspensionState[nameof(Value)] = Value;
}
else
{
// we are just navigating away so unsubscribe
App.Current.Resuming -= Current_Resuming;
}
await Task.CompletedTask;
}
Very good solution.
Template10 handling of suspend / resume is terrible.
Ditching the platform as soon as possible.
Wow if it's so terrible as you claim, help fix it instead of coming here and posting that or tell us what is terrible so we can be fix it
Most helpful comment
So this isn't a problem with T10. If an application is resumed from suspension without being terminated the app doesn't navigate, so that method won't be called. It is up to the app developer to cater for that scenario.
Without understanding your scenario, it is hard to know why you are using timer and a counter. Rather than having an integer count down the number of seconds, use time and act relative to that.
Of course, you could also subscribe to the application Resuming event if you have other things you need to do.