Метод GetStringAsync не отвечает

Я пытаюсь получить некоторые значения настраиваемых столбцов (долгота, широта) из таблицы 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;

    }

Куда и как вызвать GetUserLocationAsync? Возникает ли какое-либо исключение или выполнение просто останавливается? В последнем случае это звучит как тупик и указывает на то, что вы вызываете метод неправильно.

Cheesebaron 29.04.2018 23:11

В классе под названием MapPageViewModel общедоступная асинхронная задача <LocationDataToPostAsync> GetUserLocation () {var accesstoken = Settings.AccessToken; UserCurrentLocation = ждать _apiServices.GetUserLocationAsync (accesstoken); return UserCurrentLocation; }

Khalid Hex 29.04.2018 23:28

Выполнение не выходит за рамки ожидания в getstringasync .. исключение не создается ... вероятно, есть проблема с вызовом ... но, по крайней мере, json var должен что-то возвращать ?! потому что, как я уже сказал, когда я вызываю его из браузера, ответ 200 ОК вместе с запрошенными данными ?!

Khalid Hex 29.04.2018 23:37

Самый верхний уровень, на котором вы вызываете метод async, как это делается? Вы звоните .Result или .GetAwaiter().GetResult() по задаче, или что вы делаете? В любом случае, попробуйте добавить .ConfigureAwait(false) везде, где вы await Задача, если вам не нужно специально возвращаться в контекст, из которого вы пришли.

Cheesebaron 30.04.2018 08:06

Спасибо @Cheesebaron .. Я добавил .ConfigureAwait (false) к вызову await, и теперь он работает ..

Khalid Hex 30.04.2018 09:24

Вы знаете, почему это работает?

Cheesebaron 30.04.2018 09:41

Наткнулся ли я на эту статью medium.com/bynder-tech/c-why-you-should-use-configureawait-f‌ alse-in-your-library‌ -code-d7837dce3d7f

Khalid Hex 30.04.2018 10:05

Да, но ВЫ это понимаете? Просто ссылка на случайную статью не означает, что вы понимаете это автоматически :)

Cheesebaron 30.04.2018 10:41

Из статьи я понял, что поток пользовательского интерфейса заблокирован, и я думаю, это потому, что метод, который я вызвал из него, является проблемой, которая не реализуется 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);

Khalid Hex 30.04.2018 12:51

Проблема в том, что вы вызываете .Result по своим задачам.

Cheesebaron 30.04.2018 12:58

Итак, когда я использую .Result, выполнение никогда не закончится, и пользовательский интерфейс зависнет?

Khalid Hex 30.04.2018 13:32
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
11
878
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из вашего кода неясно, ожидается ли Task, или вы звоните .Result или .GetAwaiter().GetResult() на Task. Однако, как мы узнали в комментариях, добавление .ConfigureAwait(false) устранило вашу проблему.

Это указывает на то, что код не может вернуться в контекст, из которого он пришел, поэтому при добавлении .ConfigureAwait(false) код не возвращается в контекст.

В вашем случае контекстом, вероятно, является поток пользовательского интерфейса, и когда он пытается вернуть поток пользовательского интерфейса, он блокируется.

Наиболее вероятный сценарий, по которому поток пользовательского интерфейса заблокирован, заключается в том, что вы неправильно вызвали свою задачу. Если вы вызываете его с помощью .Result в потоке пользовательского интерфейса, вы синхронно блокируете поток пользовательского интерфейса, поэтому все, что пытается вернуться в поток пользовательского интерфейса, будет заблокировано, поскольку вы это блокируете.

Простое решение - просто добавить .ConfigureAwait(false) в ваш код. Лучшим решением было бы не блокировать поток пользовательского интерфейса, ожидая выполнения задачи.

Другие вопросы по теме