[UWP][CPP] c++ winrt how to update collection after long running async operation and show a loading icon

Kai 81 Reputation points
2019-12-03T15:49:02.093+00:00

I am trying to figure out how to show a spinning icon during long operations that update the ui. This is proving to be extremely difficult and unintuitive.

It's a simple need. Go retrieve information. (This can take a minute). While waiting show a loading icon. when done, stop showing the loading icon and update a collection that has changed.

I've prepared a sample project based on the databinding collection example from the docs.

https://github.com/camccar/collecectionasyncexample/tree/master

I use a calculate prime function to simulate long loading times. In real life I will be getting data from a sqlite database. I then add something to a collection. The loading icon is not showing.

How can i update a collection but show a loading icon while waiting?

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Fay Wang - MSFT 5,191 Reputation points
    2019-12-04T06:10:34.4+00:00

    Hello,​

    ​Welcome to our Microsoft Q&A platform!​

    By checking your code, you used concurrency::task and get() method to do an asynchronous operation. But the get() method is not appropriate for a UI thread, it will block the calling thread until the results of the asynchronous operation are available. So to avoid holding up OS threads from doing other useful work, it's better to use IAsyncOperation and co_return, because you want to return a value after the operation completes.

    Before you do compute-bound work in a coroutine, you need to return execution to the caller so that the caller isn't blocked. If you're not already doing that by co_await-ing some other operation, then you can co_await the winrt::resume_background function.

    Windows::Foundation::IAsyncAction MainPage::ClickHandler(Windows::Foundation::IInspectable const& /* sender */, Windows::UI::Xaml::RoutedEventArgs const& /* args */)
    {
        if (MainViewModel().BookSkus().Size() > 5)
        {
            MainViewModel().BookSkus().Clear();
        }
        else {
            auto stuff{ co_await RetrieveSearchResults() };
            MainViewModel().BookSkus().Append(winrt::make(stuff + winrt::to_hstring(MainViewModel().BookSkus().Size())));
        }
        pring().IsActive(false);// Set loading to true
        pring().UpdateLayout();
    }
    
    Windows::Foundation::IAsyncOperation< winrt::hstring> MainPage::RetrieveSearchResults() 
    {
        pring().IsActive(true);// Set loading to true
        pring().UpdateLayout();
    
        co_await winrt::resume_background();
    
        loopPrime(200000);
    
        co_return L"newbook";
    }
    

    Thanks.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. LUZSITA GABUTERO 1 Reputation point
    2020-06-20T07:18:52.627+00:00

    by checking code you uses concurrency task and get the method to do an asynchronous operation.

    0 comments No comments