【发布时间】:2012-08-09 07:30:06
【问题描述】:
我正在开发一个 Windows Metro 应用程序,但遇到了 UI 无响应的问题。据我所知,原因如下:
<ListView
...
SelectionChanged="ItemListView_SelectionChanged"
...
这里处理这个事件:
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 需要一段时间才能完成,因为它从 Web 服务获取数据并将其加载到屏幕上。但是,看起来 UI 正在等待它:我的猜测是直到上述事件完成。
所以我的问题是:我能做些什么呢?有没有更好的事件我可以挂钩,还是有另一种方法来处理这个?我想过启动一个后台任务,但这对我来说似乎有点过头了。
编辑:
为了澄清这个问题的严重程度,我说的是最多 3 - 4 秒无响应。这绝不是一项长期的工作。
编辑:
我尝试了下面的一些建议,但是,SelectionChanged 函数的整个调用堆栈都在使用 async/await。我已经追踪到这个声明:
myFeed = await client.RetrieveFeedAsync(uri);
在完成之前似乎不会继续处理。
编辑:
我意识到这正在变成战争与和平,但下面是使用空白地铁应用和按钮复制问题:
XAML:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<Button Click="Button_Click_1" Width="200" Height="200">test</Button>
<TextBlock x:Name="test"/>
</StackPanel>
</Grid>
后面的代码:
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";
}
}
【问题讨论】:
-
“无响应”是什么意思?如果您在页面上放置一个按钮并尝试将鼠标悬停,您会看到鼠标悬停的行为吗?你可以与页面交互吗?您是否尝试在 LoadPage 期间转换页面?如果 RetrieveFeedAsync 方法需要一段时间才能完成,它不会锁定 UI,但看起来好像什么都没有发生。
-
屏幕上的控件没有响应。鼠标移动,但应用的 UI 暂时不可用。
-
返回的 Feed 中有多少商品?
-
在上面的例子中,有 50 个......但是如果我完全删除
foreach循环,我会得到相同的行为 -
我在任何地方都看不到 LoadMyPage 的代码...请包括在内。理想情况下,请将其简化为一个简短但完整的程序来演示问题。
标签: c# .net windows-8 microsoft-metro windows-runtime