[UWP][cpp] c++ winrt uwp show loading during long operations.

Kai 81 Reputation points
2019-12-01T18:51:37.667+00:00

given a ProgressRing in the xaml such as,

ProgressRing x:Name="MyLoadingRing"

What is the recommended way to set this value to true, update the UI and then do a long running operation. For example a sqlite query.

I've tried

MyLoadingRing().IsActive(true);
MyLoadingRing().UpdateLayout();

This doesn't work. Do I need to make the long running operation Async? Seems like there should be a example of how to do this in c++winrt as it would be a very common need.

Edit: An example project that demonstrates the problem can be found here https://github.com/camccar/longloading

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Fay Wang - MSFT 5,196 Reputation points
    2019-12-02T04:07:28.657+00:00

    Hello,​


    Welcome to our Microsoft Q&A platform!​

    By checking your code, the ProgressRing you used is correct and the issue occurs because the for loop blocks the thread, it will be blocked until the function stops. So, before you do compute-bound work in a coroutine, you need to return execution to the caller (in other words, introduce a suspension point) 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. For updating UI, you can co_await the winrt::resume_foreground function to switch to a specific foreground thread. For more details about concurrency and asynchrony, you can refer to this document.

    #include "winrt/Windows.UI.Core.h"  
      
    Windows::Foundation::IAsyncAction MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)  
    {  
        pring().IsActive(true);// Set loading to true  
    	pring().UpdateLayout();  
        myButton().Content(box_value(L"Clicked"));  
        co_await winrt::resume_background();  
    	loopPrime(500000); //Long running operation here  
    	co_await winrt::resume_foreground(pring().Dispatcher());  
    	pring().IsActive(false);// Set to false when done  
    }  
    

    Thanks


0 additional answers

Sort by: Most helpful