Xamarin.Forms 和 Net.Http

Xamarin.Forms with Net.Http

伙计们,你们能告诉我这段代码有什么问题,或者我可以通过什么方式更改 Xamarin 设置以成功执行代码? Xam.Plugin.Connectivity.CrossConnectivity 说:"Device is connected to the internet",但在任何实现中 DownloadCountriesListAsync() 卡住(UWP 不工作,Android 也在清单中选择了 INTERNET 参数)。此代码在 c# 控制台应用程序中工作。

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace radacodeTestApp
{
    public class ListsDownloader
    {
        public List<Country> Countries { get; private set; }

        public ListsDownloader()
        {
            Countries = new List<Country>();
            var task = DownloadCountriesListAsync();
        }

        public async Task<bool> DownloadCountriesListAsync()
        {
            try
            {
                var vkjsonResponse = await GetResponse(@"https://api.vk.com/api.php?oauth=1&method=database.getCountries&need_all=1&v=5.60");
                var jsonObject = JObject.Parse(vkjsonResponse);
                foreach (var jO in jsonObject["response"]["items"])
                    Countries.Add(JsonConvert.DeserializeObject<Country>(jO.ToString()));

            }
            catch (OperationCanceledException)
            {
                return false;
            }
            return true;
        }

        public async Task<string> GetResponse(string url)
        {
            using (var httpClient = new HttpClient())
                return await httpClient.GetStringAsync(url);

        }


    }
    public class Country
    {
        public int Cid { get; set; }
        public string Title { get; set; }
        public override string ToString()
        {
            return Title;
        }
    }
}

从后台线程调用DownloadCountriesListAsync方法;您的代码当前正在从主线程(也称为 UIThread)调用 DownloadCountriesListAsync,这可能会导致 UIThread 冻结。

我已经在下面更新了您的代码,以展示如何从后台线程调用 DownloadCountriesListAsync 方法。

Async/Await 是一只狡猾的野兽。标记方法 async 并不意味着它会在后台线程上自动 运行;这只是意味着异步方法能够将其进程交给其 parent 线程,直到其进程完成。 @Clancey 在最近的 Xamarin 会议上做了关于 Async/Await 的精彩演讲。我强烈推荐它!

https://www.youtube.com/watch?v=jgxJbshvCXQ

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace radacodeTestApp
{
    public class ListsDownloader
    {
        public List<Country> Countries { get; private set; }

        public ListsDownloader()
        {
            Countries = new List<Country>();
            Task.Run(async () => await DownloadCountriesListAsync());
        }

        public async Task<bool> DownloadCountriesListAsync()
        {
            try
            {
                var vkjsonResponse = await GetResponse(@"https://api.vk.com/api.php?oauth=1&method=database.getCountries&need_all=1&v=5.60");
                var jsonObject = JObject.Parse(vkjsonResponse);
                foreach (var jO in jsonObject["response"]["items"])
                    Countries.Add(JsonConvert.DeserializeObject<Country>(jO.ToString()));

            }
            catch (OperationCanceledException)
            {
                return false;
            }
            return true;
        }

        public async Task<string> GetResponse(string url)
        {
            using (var httpClient = new HttpClient())
                return await httpClient.GetStringAsync(url);
        }
    }

    public class Country
    {
        public int Cid { get; set; }
        public string Title { get; set; }
        public override string ToString()
        {
            return Title;
        }
    }
}