使用Xamarin显示Android ProgressBar

时间:2016-08-16 15:32:33

标签: c# android multithreading xamarin mono

我正在通过Xamarin / MonoTouch构建Android应用程序(因此使用C#而不是Java),并希望在应用程序与服务器通信时显示ProgressBar。我一直在尝试使用异步,但我不太了解线程是如何工作的,并且我在过去的几个小时里遇到了同样的问题 - ProgressBar在我的方法之后显示打电话而不是之前。我的代码在OnCreate()方法中,我也重写为异步。这是:

        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
        };

我遇到的问题是FetchUserDetailsAsync似乎阻止了我的线程。我一直在通过关闭服务器来测试它,这需要很长的响应时间(但即使我测试像Thread.Sleep(5000)这样的东西我也有同样的问题)。在调用该方法之后,它会一个接一个地运行progbar.Visibility = ViewStates.Visible;progbar.Visibility = ViewStates.Invisible; - 我知道这一点,因为当我注释掉Invisible部分时,ProgressBar会在我的方法获得&#34;之后出现。响应&#34;从服务器。编译器也给了我像#34;跳过67帧的消息!应用程序可能在其主线程上做了太多工作。&#34;

就像我之前说过的那样,我并没有真正的线程经验,所以我很可能只是天真地做错了什么。有没有人有解决这个问题的方法?

编辑:这是FetchUserDetailsAsync的源代码:

    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;
        }
    }

2 个答案:

答案 0 :(得分:1)

看起来FetchUserDetailsAsync或ParseUserDetails正在阻止UI线程。因为Task.Sleep(5000)正在同步运行。尝试等待Task.Delay(5000);在FetchUserDetailsAsync行中查看进度条是否显示。如果确实如此,那么您可能需要进入FetchUserDetailsAsync实现以确保它实现为异步

答案 1 :(得分:1)

我想出了这个问题。我在FetchUserDetailsAsync方法中调用了GetResponse()而不是GetResponseAsync()