Xamarin.Forms GetAsync прекращает отладку без ошибок - PullRequest
0 голосов
/ 09 июня 2019

Мой код MainPage:

private void Button_Clicked(object sender, EventArgs e)
{
    Query().Wait();
    App.Current.MainPage = new Categories();
}

public async Task Query()
{
    restaurantsClient = (App.Current as App).restaurantsClient;

    try
    {
        var restaurantsNames = await restaurantsClient.GetCatalogsAsync(1);
    }
    catch (Exception ex)
    {
        var x = 0;
    }
}

Я тоже пробовал этот код, но он не работал, возникает та же проблема:

async static Task GetRequest(String URL)
{
    using (HttpClient client = new HttpClient())
    {
        // As soon as I try to step over (or even into) this next line, it crashes.
        using (HttpResponseMessage response = await client.GetAsync(URL))
        {
            using (HttpContent content = response.Content)
            {
                string data = await content.ReadAsStringAsync();

                Console.WriteLine(data);
            }
        } 
    }
}

Rest-API в C #:

var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);

Когда проект достигает этой строки, он просто умирает без каких-либо ошибок.Если я делаю это в браузере, это работает.API работает на моем ПК локально (я использую Conveyor для предоставления API).

Хорошо, я делаю видео, чтобы лучше понять, о чем я говорю: https://youtu.be/ONKTipPsEXI Как вы можете видеть после того, как я нажмуСледующий шаг в строке ответа прекратит выполнение остальной части кода.

1 Ответ

1 голос
/ 09 июня 2019

Это потому, что вы используете .Wait() из Task в потоке пользовательского интерфейса (событие Button.Clicked обрабатывается в потоке пользовательского интерфейса), вызывая взаимоблокировку. Задача ожидает, пока поток пользовательского интерфейса предоставит ей управление, и поток пользовательского интерфейса ожидает, пока задача завершит выполнение .Решением этой проблемы является добавление модификатора async в ваш обработчик событий и использование await Query() вместо Query().Wait().

private async void Button_Clicked(object sender, EventArgs e)
{
    await Query();
    App.Current.MainPage = new Categories();
}

Я также рекомендовал бы прочитать эту статью Стивен Клири по этому поводу.Кроме того, он сделал невероятную серию ( Тур по заданию ) о задачах C # в целом.

ОБНОВЛЕНИЕ:

После обновления вопроса ОП и обсуждения в комментариях к этому ответу;он думает, что есть проблема, потому что он может достичь конца GetCatalogsAsync(int) до конца GetCatalogsAsync(int, CancellationToken).Это совершенно естественно и следовало ожидать.Решение:

public async System.Threading.Tasks.Task<CatalogsInCategory> GetCatalogsAsync(int id)
{
    return await GetCatalogsAsync(id, System.Threading.CancellationToken.None);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...