伙计们和女士们,您能否告诉我此代码中存在什么问题,或者我可以以哪种方式更改 Xamarin 设置以成功执行代码? Xam.Plugin.Connectivity.CrossConnectivity
说:"设备已连接到互联网",但在任何实现中DownloadCountriesListAsync()
卡住了(UWP 不起作用,清单中也有选定的 INTERNET 参数的 Android)。此代码在 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
并不意味着它将自动在后台线程上运行;它只是意味着异步方法能够将其进程交给其父线程,直到其进程完成。@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;
}
}
}