Search code examples
c#asynchronouswindows-store-apps

How to handle event raise in await method to manage ProgressBar in Windows store app?


I want to show progressbar while method call. I have handle it as suggested in this ticket: ProgressBar button doesn't show while service call in windows store app

It doesn't wait for event which raise inside current event. i.e

public async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    loading.Visibility = Windows.UI.Xaml.Visibility.Visible;
    await initializeThePage();
    loading.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}

//following method doesn't wait for SelectionChanged event. It should wait
private async Task initializeThePage()
{
    //few service call here
    cmdStore.SelectedIndex = 1;     //this should wait until cmdStore_SelectionChanged complete its call
}

private async void cmdStore_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    //few service call here
    loading.Visibility = Windows.UI.Xaml.Visibility.Visible;
    await getOrderlistAccordingToStore(storeID);            //get store details 
    loading.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}

public async Task getOrderlistAccordingToStore(int storeID)
{
    //calls of get orderlist according to selected store
}

when cmdStore.SelectedIndex = 1; calls, it calls cmdStore_SelectionChanged method. In this case await initializeThePage(); should wait until cmdStore_SelectionChanged completed. But it doesn't wait for this event and it keep continue with next execution.

Can anybody please suggest me how to handle event which raise inside current await call?


Solution

  • cmdStore_SelectionChanged is binded to event handler and is async void. You can't directly wait for completion of execution of this method

    To you can do some workaround to handle that. First of all introduce helper methods to show/hide loader.

    int waitCounter = 0;
    void ShowLoader()
    {
        waitCounter += 1;
        if (waitCounter > 1) // Already loader is visible 
            return;
    
        loading.Visibility = Windows.UI.Xaml.Visibility.Visible;
    }
    
    void HideLoader()
    {
        waitCounter -= 1;
    
        if (waitCounter <= 0) // No more call to wait for 
           loading.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    }
    

    After that modify your implementation to look like this

    public async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
    {
        ShowLoader()
        await initializeThePage();
        HideLoader()
    }
    
    private async Task initializeThePage()
    {
        //few service call here
        cmdStore.SelectedIndex = 1;
    }
    
    private async void cmdStore_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ShowLoader();
        //few service call here
        await getOrderlistAccordingToStore(storeID);            //get store details 
        HideLoader();
    }
    
    public async Task getOrderlistAccordingToStore(int storeID)
    {
        //calls of get orderlist according to selected store
    }
    

    When page is first initialized loader will be visible and will disappear when both cmdStore_SelectionChanged and initializeThePage completes its execution.