HttpClient.GetAsync not re-enabling the button MVVM

210 Views Asked by At

Solved: See below.

Update: This fails on the HttpClient.GetAsync. It's like a "Task Finished" event isn't listened to. I'm suspecting a threading problem. It manifests itself as the button not re-enabling.

I'm getting to know the CommunityToolkit.Mvvm as introduced in James Montemagno's YouTube Channel: https://www.youtube.com/watch?v=aCxl0z04BN8
I have added an command button that calls a function that makes a call to a web api, that takes a couple of seconds to complete, but does complete successfully. Everything is working fine but for one thing.

The button disables on click, but never re-enables after the Task has finished.
The RefreshButtonText is set to "Starting" and then "Finished" as expected. What am I missing? :)

    [ICommand]
    async Task Refresh()
    {

        RefreshButtonText = "Starting";

        Price = await new RestService().GetLatestPriceAsync();
        
        RefreshButtonText = "Finished ";

    }

And on the .xaml side I have:

<Button Content="{Binding RefreshButtonText}" Command="{Binding RefreshCommand}" />

The problem is actually in this function with HttpClient.

        internal async Task<Price> GetLatestPriceAsync()
    {

        Price price;

        Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));

        try
        {

            using (HttpClient client = new HttpClient())
            {
                
                HttpResponseMessage response = new();
                response = await client.GetAsync(uri,HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(true);

                if (response.IsSuccessStatusCode)
                {
                    string content = await response.Content.ReadAsStringAsync();

                    price = JsonSerializer.Deserialize<Price>(content, serializerOptions);

                }
            }


        }
        catch (Exception ex)
        {
            Debug.WriteLine(@"\tERROR {0}", ex.Message);
        }

        return price;
    }

I have added the full project here: Link to the project on github

Workaround: The workaround is to use a standard void button call and from there call a separate function to the HttpClient. This loses the nice automatic disabling (and then re-enabling) of the button and also loses the point of having an Async Command.

        [ICommand]
    void Refresh()
    {
        _ = GetThePrice();

    }

    async Task GetThePrice()
    {

        RefreshButtonText = "Starting";

        Price = await new RestService().GetLatestPriceAsync().ConfigureAwait(false);

        RefreshButtonText = "Finished ";
    }
1

There are 1 best solutions below

0
On

Not a HttpClient problem after all.

The problem was in the CommunityToolkit.MVVM. I was using Preview2. I was told to change back to Preview1 for now and that the problem will be fixed in Preview3.