简体   繁体   中英

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM