我正在开发一个Android应用程序,由Azure上托管的ASP.NET Core应用程序提供支持。在为Xamarin.Forms(仅限Android)项目制作功能之前,我正在使用共享库项目来测试控制台应用程序项目的基本内容。
以下代码是在登录Web服务后运行的,其中Client
是HttpClient
:
public static async Task<MyClass> GetInformationAsync(string accountId)
{
HttpResponseMessage response = await Client.GetAsync(UriData + "/" + accountId);
response.EnsureSuccessStatusCode();
string responseContent = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<MyClass>(responseContent);
}
在同一台计算机/网络下,代码在控制台应用程序上完成不到一秒钟,然而,它在Xamarin.Forms.Android
项目中永远不会完成(甚至等待一分钟)。
我发现这很奇怪,因为Android客户端可以使用PostAsync
成功登录到Web服务。
然而,Android客户端和控制台客户端如何调用GetInformationAsync
有所不同。
当Console客户端异步调用它时:
private static async void TestDataDownload()
{
...
var data = await WebApiClient.GetInformationAsync(myId);
}
Android客户端同步调用
public void MainPage()
{
...
var data = WebApiClient.GetInformationAsync(myId).Result;
}
答案 0 :(得分:13)
您似乎遇到了某种僵局。您可能希望将代码包含在实际调用GetInformationAsync
的位置,因为它可能是问题来源所在。
您可以通过以下方式解决问题:
GetInformationAsync
GetInformationAsync
在ConfigureAwait(false)
中对异步调用进行后缀,以便在每次方法调用时都不切换上下文。因此,您的GetInformationAsync
方法如下:
public static async Task<MyClass> GetInformationAsync(string accountId)
{
var response = await Client.GetAsync(UriData + "/" + accountId).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<MyClass>(responseContent);
}
然后,如果你在某处调用它,你需要它返回相同的上下文,即。如果您需要更新UI:
var myClass = await GetInformationAsync(accountId);
// update UI here...
否则,如果您不需要返回相同的上下文:
var myClass = await GetInformationAsync(accountId).ConfigureAwait(false);