Я пытаюсь получить некоторые значения настраиваемых столбцов (долгота, широта) из таблицы ASPNetUsers из БД. Когда я отправляю браузер выброса запроса Get, я получаю 200 ОК с запрошенным json .. но когда я пытаюсь использовать GetStringAsync для десериализации ответ в моем приложении xamarin я не получаю ответа.
В классе AccountController
// POST api/Account/GetUserPostion
[Route("GetUserPostion")]
public LocationDataToPostAsync GetUserPostion()
{
var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
var manager = new ApplicationUserManager(store);
LocationDataToPostAsync locationData = new LocationDataToPostAsync();
var model = manager.FindById(User.Identity.GetUserId());
locationData.UserId = User.Identity.GetUserId();
if (model.Longitude != null) locationData.Longitude = (double) model.Longitude;
if (model.Latitude != null) locationData.Latitude = (double) model.Latitude;
return locationData;
}
В классе ApiService в приложении форм xamarin
public async Task<LocationDataToPostAsync> GetUserLocationAsync(string accessToken)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var json = await client.GetStringAsync("http://10.0.2.2:45455/api/Account/GetUserPostion");
var location = JsonConvert.DeserializeObject<LocationDataToPostAsync>(json);
return location;
}
В классе под названием MapPageViewModel общедоступная асинхронная задача <LocationDataToPostAsync> GetUserLocation () {var accesstoken = Settings.AccessToken; UserCurrentLocation = ждать _apiServices.GetUserLocationAsync (accesstoken); return UserCurrentLocation; }
Выполнение не выходит за рамки ожидания в getstringasync .. исключение не создается ... вероятно, есть проблема с вызовом ... но, по крайней мере, json var должен что-то возвращать ?! потому что, как я уже сказал, когда я вызываю его из браузера, ответ 200 ОК вместе с запрошенными данными ?!
Самый верхний уровень, на котором вы вызываете метод async, как это делается? Вы звоните .Result или .GetAwaiter().GetResult() по задаче, или что вы делаете? В любом случае, попробуйте добавить .ConfigureAwait(false) везде, где вы await Задача, если вам не нужно специально возвращаться в контекст, из которого вы пришли.
Спасибо @Cheesebaron .. Я добавил .ConfigureAwait (false) к вызову await, и теперь он работает ..
Вы знаете, почему это работает?
Наткнулся ли я на эту статью medium.com/bynder-tech/c-why-you-should-use-configureawait-f alse-in-your-library -code-d7837dce3d7f
Да, но ВЫ это понимаете? Просто ссылка на случайную статью не означает, что вы понимаете это автоматически :)
Из статьи я понял, что поток пользовательского интерфейса заблокирован, и я думаю, это потому, что метод, который я вызвал из него, является проблемой, которая не реализуется await в вызове GetUserLocation >> public void LocationMethod () {MapPageViewModel model = new MapPageViewModel () ; Задача <LocationDataToPostAsync> userLocation = model.GetUserLocation (); var result = userLocation.Result; var position1 = new Position (result.Latitude, result.Longitude);
Проблема в том, что вы вызываете .Result по своим задачам.
Итак, когда я использую .Result, выполнение никогда не закончится, и пользовательский интерфейс зависнет?

Из вашего кода неясно, ожидается ли Task, или вы звоните .Result или .GetAwaiter().GetResult() на Task. Однако, как мы узнали в комментариях, добавление .ConfigureAwait(false) устранило вашу проблему.
Это указывает на то, что код не может вернуться в контекст, из которого он пришел, поэтому при добавлении .ConfigureAwait(false) код не возвращается в контекст.
В вашем случае контекстом, вероятно, является поток пользовательского интерфейса, и когда он пытается вернуть поток пользовательского интерфейса, он блокируется.
Наиболее вероятный сценарий, по которому поток пользовательского интерфейса заблокирован, заключается в том, что вы неправильно вызвали свою задачу. Если вы вызываете его с помощью .Result в потоке пользовательского интерфейса, вы синхронно блокируете поток пользовательского интерфейса, поэтому все, что пытается вернуться в поток пользовательского интерфейса, будет заблокировано, поскольку вы это блокируете.
Простое решение - просто добавить .ConfigureAwait(false) в ваш код. Лучшим решением было бы не блокировать поток пользовательского интерфейса, ожидая выполнения задачи.
Куда и как вызвать
GetUserLocationAsync? Возникает ли какое-либо исключение или выполнение просто останавливается? В последнем случае это звучит как тупик и указывает на то, что вы вызываете метод неправильно.