HttpClient.GetAsync 永远不会在 Xamarin.Android 上返回 [英] HttpClient.GetAsync never returns on Xamarin.Android
问题描述
我正在开发一个由 Azure 上托管的 ASP.NET Core 应用程序支持的 Android 应用程序.在为 Xamarin.Forms(仅限 Android)项目制作功能之前,我正在使用共享库项目来测试控制台应用程序项目上的基本内容.
以下代码在登录到 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
- 使用
ConfigureAwait(false)
对GetInformationAsync
中的异步调用进行后缀处理,以免在每次方法调用时都切换上下文.
- Not calling
GetInformationAsync
in a sync way - Postfixing your async calls in
GetInformationAsync
withConfigureAwait(false)
to not switch context on every method call.
所以你的 GetInformationAsync
方法看起来像:
So your GetInformationAsync
method would look like:
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);
}
然后如果你在某个地方调用它,你需要它在相同的上下文中返回,即如果您需要更新用户界面:
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屋!