Issues with ProgressBar and async/await

KasperBorysKasperBorys USMember
edited August 2016 in Xamarin.Android

I am building an app that allows users to log in, and would like to display a ProgressBar while the app is communicating with the server. I have been attempting to do this using async, but I don't have a good understanding of how threading works, and I've been running into the same issue for the past few hours - the ProgressBar shows after my method call rather than before. My code is in the OnCreate() method, which I have also overridden to be async. Here it is:

        loginButton.Click += async (sender, e) =>
        {
            progbar.Visibility = ViewStates.Visible;

            var userFetcher = new UserFetcher();
            var json = await userFetcher.FetchUserDetailsAsync(/*parameters*/);
    //the above method is async and returns a Task<JsonValue>
            ParseUserDetails(json); //another method I created

            progbar.Visibility = ViewStates.Invisible;
            //do some stuff using the parsed data
        };

The issue I'm running into is that the FetchUserDetailsAsync seems to be blocking my thread. I have been testing this by shutting the server off so that it takes a long response time (but even when I test stuff like Thread.Sleep(5000) I have the same issue). After the method has been called, it runs both progbar.Visibility = ViewStates.Visible; and progbar.Visibility = ViewStates.Invisible; right after one another - I know this because when I comment out the Invisible part, the ProgressBar appears after my method got a "response" from the server. I have also gotten messages from the compiler like "Skipped 67 frames! The application may be doing too much work on its main thread."

Like I said earlier, I'm not really experienced with threading, so it's very possible I'm just naively doing something wrong. Any ideas what my issue might be?

Posts

  • KasperBorysKasperBorys USMember

    Some further investigation and tinkering leads me to believe that the issue might be with the FetchUserDetailsAsync method. Here is the source code in case anybody can figure out some insight:

        public async Task<JsonValue> FetchUserDetailsAsync(string url, string username, string password)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
            request.ContentType = "application/json";
            request.Method = "GET";
    
            string myBasicHeader = AuthenticationHelper.MakeHeader(username, password);
    
            request.Headers.Add("Authorization", "Basic " + myBasicHeader);
    
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
                        return jsonDoc;
                    }
                }
            }
            catch (WebException e)
            {
                Console.WriteLine(e.ToString());
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    var response = e.Response as HttpWebResponse;
                    if (response != null)
                    {
                        Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
                    }
                    else
                    {
                        Console.WriteLine("No http status code available");
                    }
                }
                return null;
            }
        }
    
  • KasperBorysKasperBorys USMember

    I finally figured it out. After scrutinizing the code of FetchUserDetailsAsync, I realized that I was calling GetResponse() rather than GetResponseAsync()

Sign In or Register to comment.