#android #multithreading #xamarin #httpclient #deadlock
#Android #многопоточность #xamarin #httpclient #взаимоблокировка
Вопрос:
У нас возникла проблема с классом System.Net.Http.HttpClient. Приведенный ниже код отлично работает со многими устройствами Android, за исключением некоторых, из которых два устройства перечислены ниже. Выполнение застревает на следующей строке, блокируя поток, из-за чего приложение перестает отвечать, что приводит к повышению ANR (приложение не отвечает).
var resp = await client.PostAsync(url, content);
Затронутые устройства:
Samsung Note 9 (Android 9.0) и
Samsung S7 (Android 8.0)
Недавно мы обновили некоторые зависимости, которые требовались для обновления Google Maps и SMS Retriever API.
Вот исходный код:
async void ExecuteLogin()
{
try
{
var isOperationSuccessful = await PerformServiceCall(async () =>
{
await DependencyService.Get<DataStore.Abstractions.IAuthService>().LoginAsync(Username, Password.Encrypt());
});
}
catch (Exception ex)
{
}
finally
{
}
}
public async Task LoginAsync(string username, string password)
{
var response = await PostHelper.DoRequest<LoginRequest, LoginResponse>(ServiceURL.Login,
new LoginRequest()
{
UserId = username,
Password = password,
});
ApiResponseValidator.ValidateResponse(response, "Unable to login");
GlobalHelper.SessionId = response?.SessionId;
GlobalHelper.Username = username;
}
public static async Task<U> DoRequest<T,U>(string url, T obj)
{
var result = "{}";
try
{
using (var client = new HttpClient())
{
string datasent = JsonConvert.SerializeObject(obj);
HttpContent content = new StringContent(datasent,
Encoding.UTF8,
"application/json");
client.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident / 6.0)");
var resp = await client.PostAsync(url, content);
result = resp.Content.ReadAsStringAsync().Resu<
return JsonConvert.DeserializeObject<U>(result);
}
}
catch (Exception ex)
{
throw new Exception($"Unable to service the request at this time. {ex.Message}", ex);
}
}
protected async Task<bool> PerformServiceCall(Func<Task> serviceCallAction,
Action<GenericException> onError = null)
{
if (!CrossConnectivity.Current.IsConnected)
{
DisplayInfo("Looks like you're not connected to the internet.", "DISMISS", null);
return false;
}
if (IsLoading)
{
return false;
}
try
{
IsLoading = true;
await serviceCallAction?.Invoke();
return true;
}
catch (GenericException ex) when (ex.ExType == ExceptionType.SessionTimeOut)
{
SessionTimedOut<BaseViewModel>();
Logger.Report(ex, Severity.Error);
return false;
}
catch (CriticalException ex)
{
if (onError != null)
{
onError.Invoke(ex);
}
else
{
DisplayCriticalInfo(ex.Title, ex.Message);
}
Logger.Report(ex, Severity.Error);
return false;
}
catch (GenericException ex)
{
if (onError != null)
{
onError.Invoke(ex);
}
else
{
DisplayInfo(ex.Message);
}
Logger.Report(ex, Severity.Error);
return false;
}
catch (Exception ex)
{
DisplayInfo(ex.Message);
Logger.Report(ex, Severity.Error);
return false;
}
finally
{
IsLoading = false;
}
}
Вот список пакетов с их версией для справки, определенной в packages.config в проекте Xamarin.
<package id="ExifLib.PCL" version="1.0.1" targetFramework="portable-net45 win wpa81 MonoAndroid10 xamarinios10 MonoTouch10" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="portable45-net45 win8 wpa81" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="portable45-net45 win8 wpa81" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="portable45-net45 win8 wpa81" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="portable45-net45 win8 wpa81" />
<package id="Plugin.Fingerprint" version="1.4.9" targetFramework="portable45-net45 win8 wpa81" />
<package id="Plugin.Permissions" version="2.0.1" targetFramework="portable45-net45 win8 wpa81" />
<package id="sameerIOTApps.Plugin.SecureStorage" version="1.2.1" targetFramework="portable45-net45 win8 wpa81" />
<package id="Syncfusion.Xamarin.SfCalendar" version="14.3.0.49" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xam.Plugin.Connectivity" version="2.3.0" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xam.Plugin.Geolocator" version="3.0.4" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xamarin.Build.Download" version="0.4.6" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xamarin.Forms" version="3.2.0.871581" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xamarin.Forms.CarouselView" version="2.3.0-pre2" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xamarin.Forms.GoogleMaps" version="3.0.4" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xamarin.Forms.Maps" version="2.3.4.247" targetFramework="portable45-net45 win8 wpa81" />
<package id="Xamvvm.Forms" version="1.0.0" targetFramework="portable45-net45 win8 wpa81" />
<package id="XLabs.Core" version="2.2.0-pre02" targetFramework="portable45-net45 win8 wpa81" />
<package id="XLabs.Forms" version="2.2.0-pre02" targetFramework="portable45-net45 win8 wpa81" />
<package id="XLabs.IoC" version="2.2.0-pre02" targetFramework="portable45-net45 win8 wpa81" />
<package id="XLabs.Platform" version="2.2.0-pre02" targetFramework="portable45-net45 win8 wpa81" />
<package id="XLabs.Serialization" version="2.2.0-pre02" targetFramework="portable45-net45 win8 wpa81" />
Комментарии:
1. используйте
await
vs.Result
при вызове ReadAsStringAsync2. У меня такая же проблема — вы нашли решение?