WinRT的 - 加载数据,同时保持用户界面响应 [英] WinRT - Loading data while keeping the UI responsive
问题描述
我在开发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屋!