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

eivnm1vs  于 2024-01-04  发布在  Android
关注(0)|答案(2)|浏览(153)

我正在开发一个Android应用程序,由Azure上托管的ASP.NET Core应用程序备份。我正在使用一个共享库项目来测试控制台应用程序项目上的基本内容,然后再为Xamarin.Forms(仅限Android)项目开发功能。
以下代码是在登录web service后运行的,其中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);
}

字符串
在同一台计算机/网络下,代码在Console应用程序上不到一秒钟就完成了,但是,在Xamarin.Forms.Android项目中,它从来没有完成(甚至等待一分钟)。
我觉得这很奇怪,因为Android客户端可以使用PostAsync成功登录到Web服务。
但是,Android客户端和Console客户端调用GetInformationAsync的方式有所不同。
当Console客户端异步调用它时:

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


Android客户端同步调用它

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

hm2xizp9

hm2xizp91#

看起来你遇到了某种类型的死锁,你可能想在实际调用GetInformationAsync的地方包含代码,因为这可能是问题的根源。
您可以通过以下方式解决您的问题:
1.不以同步方式调用GetInformationAsync
1.在GetInformationAsync中使用ConfigureAwait(false)来后置你的aprc调用,以避免在每次方法调用时切换上下文。
所以你的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);

aor9mmx1

aor9mmx12#

如果您使用的是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>

相关问题