WinRT - Loading data while keeping the UI responsive

Viewed 5350

I'm developing a Windows Metro app, and am getting an issue with the UI becoming unresponsive. As far as I can tell, the cause is as follows:

    <ListView
...
        SelectionChanged="ItemListView_SelectionChanged"            
...

This event is handled here:

    async void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (this.UsingLogicalPageNavigation()) this.InvalidateVisualState();

        MyDataItem dataItem = e.AddedItems[0] as MyDataItem;
        await LoadMyPage(dataItem);
    }

    private async Task LoadMyPage(MyDataItem dataItem)
    {            
        SyndicationClient client = new SyndicationClient();
        SyndicationFeed feed = await client.RetrieveFeedAsync(new Uri(FEED_URI));                    

        string html = ConvertRSSToHtml(feed)
        myWebView.NavigateToString(html, true);            
    }

LoadMyPage takes a while to complete, as it gets data from a web service and loads it onto the screen. However, it looks like the UI is waiting for it: my guess is that until the above event completes.

So my question is: what can I do about this? Is there a better event I can hook into, or is there another way to handle this? I thought about starting a background task, but that seems like overkill to me.

EDIT:

Just to clarify the scale of this problem, I'm talking about a maximum of 3 - 4 seconds unresponsive. This is by no means a long running job.

EDIT:

I've tried some of the suggestion below, however, the entire call stack from the SelectionChanged function is using async/await. I've tracked it down to this statement:

myFeed = await client.RetrieveFeedAsync(uri);

Which doesn't seem to be continuing processing until it's complete.

EDIT:

I realise this is turning into War & Peace, but below is a replication of the problem using a blank metro app and a button:

XAML:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <Button Click="Button_Click_1" Width="200" Height="200">test</Button>
        <TextBlock x:Name="test"/>
    </StackPanel>
</Grid>

Code behind:

    private async void Button_Click_1(object sender, RoutedEventArgs e)
    {
        SyndicationFeed feed = null;

        SyndicationClient client = new SyndicationClient();
        Uri feedUri = new Uri(myUri);

        try
        {
            feed = await client.RetrieveFeedAsync(feedUri);

            foreach (var item in feed.Items)
            {       
                test.Text += item.Summary.Text + Environment.NewLine;                    
            }
        }
        catch
        {
            test.Text += "Connection failed\n";
        }
    }
5 Answers
Related