0

My application retrieves data from server by asynchronous calls to apis. It works fine as long as the user remains in app. After implementing Fast App Resume, when app resumes after clicking on the tile, the control comes to the page on which user left previously.

If there was any asynchronous call running when user had deactivated the app(hit the start button previously), it throws the following exception.Exception.

In fact this exception is thrown by the following code.

    private async Task<string> httpRequest(HttpWebRequest request)
    {
        string received;

        using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory
            .FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
        {
            using (var responseStream = response.GetResponseStream())
            {
                using (var sr = new StreamReader(responseStream))
                {
                    //cookieJar = request.CookieContainer;
                    //responseCookies = response.Cookies;
                    received = await sr.ReadToEndAsync();
                }
            }
        }

        return received.Replace("[{}]", "[]")
                .Replace("[{},{}]", "[]")
                .Replace("\"subcat_id\":\"\"", "\"subcat_id\":\"0\"");
    } 

Is there any way to stop execution of the async method on OnNavigatedFrom method when user deactivates the app? Or is there any way to preserve the state of async call and resume it again?

Thanks in advance.

LojiSmith
  • 282
  • 3
  • 20

1 Answers1

1

When your App is Deactivated then all its proccesses are stopped (MSDN):

When the user navigates forward, away from an app, after the Deactivated event is raised, the operating system will attempt to put the app 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.

Your async method should allow Cancellation - here you have an example of Cancelling.

Use CancellationTokenSource and then in your Deactivation event or OnNavigatedFrom put:

if (cts != null) cts.Cancel();

In your case you should also implement AsyncReading (via buffer) from response to enable token.ThrowIfCancealltionRequested(). You can look here - method 3 and here. Maybe it will help.

Community
  • 1
  • 1
Romasz
  • 29,662
  • 13
  • 79
  • 154
  • thanks for a quick response, well i have two problems, one is that i am loading initial data in overridden method onNavigatedTo() only if (e.NavigationMode == NavigationMode.New) . My bad, please let me know on which events should we load data from server. PageLoad occures everytime even we navigate back etc. I just want the data for first time. – LojiSmith Mar 24 '14 at 09:33
  • second thing is this in my app i have around 20 pages and my client has asked to implement the app resume, so i need any solution that takes less time. – LojiSmith Mar 24 '14 at 09:34
  • @LojiSmithKaleem With the first problem you have few possibilities. IMO loading data in Application_Launching (where you have limited time) is not a good idea, so OnNavigatedTo can be a good idea, I would only provide some indicator (that data is being downloaded), you can easily provide a boolean that will infor if the data is already downloaded, then upon deactivation you can check it. – Romasz Mar 24 '14 at 09:39
  • @LojiSmithKaleem I think there are many good solutions and it also depends on your specific app purposes and lifecycle. I only add that you should also read/implement about Tombstone case - where you will have to load your data once again in most of the cases. – Romasz Mar 24 '14 at 09:41
  • fine, will tombstoning work with async calls or not? currently i am just catching the exception and ignore it and send the call again and it works. For example while loading the reviews if user deactivates the app, when he gets back the loadReviews() method will catch the exception and if (webEx.Status == System.Net.WebExceptionStatus.RequestCanceled) it ignores otherwise shows the error message. In OnNavigatedTo i again call the loadReviews() its working. Is it a workable solution for instance? or maintaining states will fix issues of async too? – LojiSmith Mar 24 '14 at 10:25
  • @LojiSmithKaleem As for tombstoning - it doesn't depend on your App - your App is deactiveted and goes to Dormant State from where it can be tombstoned [MSDN](http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff817008(v=vs.105).aspx). The problem in your case might be that most of resources is released. The would be if you had tested it - go to Project Properties -> Debug -> tombstone upon deactivation. Then you will know what happens. – Romasz Mar 24 '14 at 10:31
  • @LojiSmithKaleem As for catching the exception - in simple cases it should work (check if there is no possibility that there will be a mess with data, some is loaded, some canceled, some parsed and so on). IMO it will be much better if you had cancelled your method (then you know what happens). – Romasz Mar 24 '14 at 10:33