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;
}
}
}
伙计们,你们能告诉我这段代码有什么问题,或者我可以通过什么方式更改 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;
}
}
}