【问题标题】:HttpClient.GetAsync never returns on Xamarin.AndroidHttpClient.GetAsync 永远不会在 Xamarin.Android 上返回
【发布时间】:2016-06-29 00:49:06
【问题描述】:

我正在开发一个由 Azure 上托管的 ASP.NET Core 应用程序支持的 Android 应用程序。在为 Xamarin.Forms(仅限 Android)项目创建功能之前,我正在使用共享库项目来测试控制台应用程序项目上的基本内容。
以下代码在登录到 Web 服务后运行,其中ClientHttpClient

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 的方式有所不同。

当控制台客户端异步调用它时:

 private static async void TestDataDownload()
 {
      ...
      var data = await WebApiClient.GetInformationAsync(myId);
 }

Android客户端同步调用

 public void MainPage()
 {
      ...
      var data = WebApiClient.GetInformationAsync(myId).Result;
 }

【问题讨论】:

  • 你使用的是本地主机还是本地IP地址?
  • @AthulHarikumar Web 服务托管在 Azure Web Apps 的免费实例上

标签: c# android xamarin asp.net-core


【解决方案1】:

您似乎遇到了某种僵局。您可能希望在实际调用 GetInformationAsync 的位置包含代码,因为它可能是问题的根源所在。

您可以通过以下方式解决您的问题:

  1. 不以同步方式调用GetInformationAsync
  2. 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);

【讨论】:

  • 以异步方式调用 GetInformationAsync 有效,无需更改 GetInformationAsync 本身。谢谢!
  • ConfigureAwait(false) 对我有用。谢谢!
  • 这是我找到的关于这个问题的最佳答案。 ConfigureAwait(false) 为我工作。谢谢@Cheesebaron。
【解决方案2】:

如果您使用的是 http 而不是 https。 确保在 Android Mainfest for android 中添加以下行。 有关更多信息,请参阅以下文档https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/http-stack?tabs=windows

android:usesCleartextTraffic="true"

完整的 Mainfest 文件是

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.maximop2p" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
    <application android:label="MaximoP2P.Android" android:theme="@style/MainTheme"
                 android:usesCleartextTraffic="true"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

【讨论】:

  • 首先,这是一个非常古老的问题。其次,是什么让您认为使用 HTTPS 或 HTTP 对发布的问题有影响?
猜你喜欢
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 2011-07-25
  • 1970-01-01
  • 2012-10-02
  • 2013-02-18
相关资源
最近更新 更多