WinRT的 - 加载数据,同时保持用户界面响应 [英] WinRT - Loading data while keeping the UI responsive

查看:268
本文介绍了WinRT的 - 加载数据,同时保持用户界面响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在开发Windows地铁应用程序,并正在一个问题与UI变得反应迟钝。据我所知道的,原因如下:

 <的ListView
...
        的SelectionChanged =ItemListView_SelectionChanged
...
 

此事件在这里处理的:

 异步无效ItemListView_SelectionChanged(对象发件人,SelectionChangedEventArgs E)
    {
        如果(this.UsingLogicalPageNavigation())this.InvalidateVisualState();

        MyDataItem的DataItem = e.AddedItems [0]作为MyDataItem;
        等待LoadMyPage(DataItem的);
    }

    私人异步任务LoadMyPage(MyDataItem的DataItem)
    {
        SyndicationClient客户端=新SyndicationClient();
        SyndicationFeed饲料=等待client.RetrieveFeedAsync(新的URI(FEED_URI));

        字符串的HTML = ConvertRSSToHtml(饲料)
        myWebView.NavigateToString(HTML,真正的);
    }
 

LoadMyPage 需要一段时间才能完成,因为它得到的数据从一个Web服务,并加载它搬上银幕。不过,它看起来像UI正在等待它。我的猜测是,直到上述事件完成

所以我的问题是:我该怎么办呢?有没有更好的情况下,我可以钩到,或者有另一种方式来处理呢?我想过启动一个后台任务,但似乎有点小题大做了我。

编辑:

我想弄清楚这个问题的严重性,我说的最多的3 - 4秒反应迟钝。这绝不是一个长期运行的工作。

编辑:

我试过下面的一些建议,然而,从的SelectionChanged 函数的整个调用堆栈使用异步/等待。我跟踪它到这条语句:

  myFeed =等待client.RetrieveFeedAsync(URI);
 

看起来这并没有被继续处理,直到它完成。

编辑:

我意识到这是演变成战争和放大器;和平,但下面是问题的使用空白的地铁应用程序和一个按钮复制:

XAML:

 <网格背景={的StaticResource ApplicationPageBackgroundThemeBrush}>
    < StackPanel的>
        <按钮单击=Button_Click_1WIDTH =200高度=200>测试< /按钮>
        < TextBlock的X:名称=测试/>
    < / StackPanel的>
< /网格>
 

身后code:

 专用异步无效Button_Click_1(对象发件人,RoutedEventArgs E)
    {
        SyndicationFeed饲料= NULL;

        SyndicationClient客户端=新SyndicationClient();
        乌里feedUri =新的URI(myUri);

        尝试
        {
            饲料=等待client.RetrieveFeedAsync(feedUri);

            的foreach(在feed.Items VAR项)
            {
                test.Text + = item.Summary.Text + Environment.NewLine;
            }
        }
        抓住
        {
            test.Text + =连接失败\ N的;
        }
    }
 

解决方案

试试这个......

  SyndicationFeed饲料= NULL;

SyndicationClient客户端=新SyndicationClient();

VAR feedUri =新的URI(myUri);

尝试 {
    VAR任务= client.RetrieveFeedAsync(feedUri).AsTask();

    task.ContinueWith((X)=> {
        VAR的结果= x.Result;

        Parallel.ForEach(result.Items,项目=> {
            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
            ()=>
            {
                test.Text + = item.Title.Text;
            });
       });
   });
}
赶上(例外前){}
 

我通过添加一个按钮,使用网格的应用程序模板的应用程序试了一下我的机器上。我可以滚动项目的电网来回,而我更新了页面的标题没有问题。虽然我没有很多的项目,以它去真快,所以这是很难100%肯定的。

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";
        }
    }

解决方案

Give this a try...

SyndicationFeed feed = null;

SyndicationClient client = new SyndicationClient();

var feedUri = new Uri(myUri);

try {
    var task = client.RetrieveFeedAsync(feedUri).AsTask();

    task.ContinueWith((x) => {
        var result = x.Result;

        Parallel.ForEach(result.Items, item => {
            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
            () =>
            {
                test.Text += item.Title.Text;
            });
       });     
   });
}
catch (Exception ex) { }

I tried it on my machine by adding a button to an app using the Grid app template. I could scroll the grid of items back and forth while I updated the title of the page without problem. Though I didn't have a lot of items to it went really fast so it was tough to be 100% positive.

这篇关于WinRT的 - 加载数据,同时保持用户界面响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆