HttpClient.GetAsync永远不会在Xamarin.Android上返回 [英] HttpClient.GetAsync never returns on Xamarin.Android
问题描述
我正在开发一个Android应用程序,该应用程序由Azure上托管的ASP.NET Core应用程序备份.在使用Xamarin.Forms(仅Android)项目的功能之前,我正在使用共享的Library项目来测试Console Application项目上的基本内容.
以下代码段在登录到Web服务后运行,其中Client
是HttpClient
:
I am working on an Android application, backed up by an ASP.NET Core application hosted on Azure. I am using a shared Library project to test basic stuff on a Console Application project before making the functionalities for the Xamarin.Forms (Android-only) project.
The following piece of code is run after logging into the web service, where Client
is a 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服务.
Under the same computer/network, the code finishes in less than a second on the Console application, however, it never finishes (even waited a minute) in the Xamarin.Forms.Android
project.
I find this weird since the Android client can successfully login to the web service using PostAsync
.
但是,Android客户端和控制台客户端调用GetInformationAsync
的方式有所不同.
There is a difference, however, on how the Android client and the Console client call GetInformationAsync
.
当控制台客户端异步调用它时:
While the Console client calls it asynchronously:
private static async void TestDataDownload()
{
...
var data = await WebApiClient.GetInformationAsync(myId);
}
Android客户端同步调用它
The Android client calls it synchronously
public void MainPage()
{
...
var data = WebApiClient.GetInformationAsync(myId).Result;
}
推荐答案
似乎您遇到了某种僵局.您可能希望在实际调用GetInformationAsync
的地方包含代码,因为这可能是问题根源所在的地方.
It seems like you are experiencing a deadlock of some sort. You might want to include the code where you actually call GetInformationAsync
, as it is probably where the problem source is.
您可以通过以下方法解决问题:
You can probably fix your issue by:
- 不以同步方式调用
GetInformationAsync
- 将
GetInformationAsync
中的异步调用后缀为ConfigureAwait(false)
,以免在每个方法调用时切换上下文.
- Not calling
GetInformationAsync
in a sync way - Postfixing your async calls in
GetInformationAsync
withConfigureAwait(false)
to not switch context on every method call.
所以您的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:
Then if you call it somewhere you need it to return back on the same context, I.e. if you need to update UI:
var myClass = await GetInformationAsync(accountId);
// update UI here...
否则,如果您不需要需要在相同的上下文中返回:
Otherwise if you don't need to return on the same context:
var myClass = await GetInformationAsync(accountId).ConfigureAwait(false);
这篇关于HttpClient.GetAsync永远不会在Xamarin.Android上返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!