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);
}
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
.
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);
}
The Android client calls it synchronously
public void MainPage()
{
...
var data = WebApiClient.GetInformationAsync(myId).Result;
}
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
in a sync wayGetInformationAsync
with ConfigureAwait(false)
to not switch context on every method call.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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With