Xamarin.Forms 与 Net.Http [关闭]

Posted

技术标签:

【中文标题】Xamarin.Forms 与 Net.Http [关闭]【英文标题】:Xamarin.Forms with Net.Http [closed] 【发布时间】:2017-01-08 20:49:47 【问题描述】:

各位男士女士,您能告诉我这段代码有什么问题吗?或者我可以通过哪些方式更改 Xamarin 设置以成功执行代码? Xam.Plugin.Connectivity.CrossConnectivity 说:“设备已连接到互联网”,但在任何实现中 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;
        
    

【问题讨论】:

你不是,也不能是,等待它完成。不要在构造函数中这样做。 我不是在等待构造函数完成。仔细看 完全正确;这就是问题 伙计,这是异步进程。它成功了。问题是另一面。此过程停留在获取 http 响应并等待结果程序可以完全冻结 【参考方案1】:

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

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

Async/Await 是一个棘手的问题。标记方法async 并不意味着它会自动在后台线程上运行;它只是意味着异步方法能够将其进程让给其父线程,直到其进程完成。 @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;
        
    

【讨论】:

谢谢你,布兰登

以上是关于Xamarin.Forms 与 Net.Http [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

System.Net.Http.HttpRequestException 异常将在物理设备上运行 xamarin UI 测试

Catel 与 Xamarin.Forms

Xamarin.Forms:与平台无关的应用程序菜单

Xamarin.Forms:与 Azure MobileServices 同步太慢

TeamCity 上的 Xamarin 表单:Xamarin.Forms 任务与目标不匹配

是否可以将 Xaml 设计器或智能感知与 Xamarin.Forms 一起使用?