LOL Jovem
LOL Jovem

Reputation: 207

Xamarin.Forms GetAsync stops debugging without error

My MainPage code-behind:

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;
    }
}

I tried this code too but didn't work, happens the same problem:

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 in C#:

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

When the project reach this line it just die without showing any error. If I do it in the browser it works. The API is running locally in my PC (Im using Conveyor to expose the API).

Ok I make a video to see better what Im talking about: https://youtu.be/ONKTipPsEXI As you can see after I click Next Step in response line stop executing the rest of the code.

Upvotes: 0

Views: 171

Answers (1)

Aly Elhaddad
Aly Elhaddad

Reputation: 1943

That's because you're using .Wait() of a Task on the UI thread (Button.Clicked event is handled on the UI thread) causing a deadlock. The task is waiting for the UI thread to give it control and the UI thread is waiting for the task to complete. The solution to this is to add async modifier to your event handler and use await Query() instead of Query().Wait().

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

I'd also recommend reading this article by Stephen Cleary about this matter. Moreover, he's made a fabulous series (A Tour of Task) about C# tasks in general.

UPDATE:

After OP's question update and discussion in this answer's comments; he thinks that there's a problem because he can reach the end of GetCatalogsAsync(int) before the end of GetCatalogsAsync(int, CancellationToken). That's completely natural and is to be expected. Solution:

public async System.Threading.Tasks.Task<CatalogsInCategory> GetCatalogsAsync(int id)
{
    return await GetCatalogsAsync(id, System.Threading.CancellationToken.None);
}

Upvotes: 1

Related Questions