HttpClient.GetAsync 永远不会在 Xamarin.Android 上返回 [英] HttpClient.GetAsync never returns on Xamarin.Android

查看:27
本文介绍了HttpClient.GetAsync 永远不会在 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:

  1. 不以同步方式调用GetInformationAsync
  2. 使用 ConfigureAwait(false)GetInformationAsync 中的异步调用进行后缀处理,以免在每次方法调用时都切换上下文.
  1. Not calling GetInformationAsync in a sync way
  2. Postfixing your async calls in GetInformationAsync with ConfigureAwait(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆