HttpClient.GetAsync 在 Xamarin.Android 上永远不会返回

问题描述 投票:0回答:3

我正在开发一个 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

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

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

Android客户端同步调用

public void MainPage() { ... var data = WebApiClient.GetInformationAsync(myId).Result; }
    
c# android xamarin asp.net-core
3个回答
20
投票
您似乎遇到了某种僵局。您可能希望包含实际调用

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);
    

0
投票
Adnan Malik 的解决方案对我有用


-1
投票
如果您使用的是 http 而不是 https。 确保在 Android Mainfest for android 中添加以下行。 有关更多信息,请参阅以下文档

https://learn.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>
    
© www.soinside.com 2019 - 2024. All rights reserved.