WinRT - ładowanie danych przy zachowaniu responsywności interfejsu użytkownika
Opracowuję aplikację Windows Metro i pojawia się problem z brakiem odpowiedzi interfejsu użytkownika. O ile wiem, przyczyna jest następująca:
<ListView
...
SelectionChanged="ItemListView_SelectionChanged"
...
To wydarzenie jest obsługiwane tutaj:
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
zajmuje trochę czasu, ponieważ pobiera dane z usługi internetowej i ładuje ją na ekran. Wygląda jednak na to, że interfejs użytkownika czeka na to: zgaduję, że dopóki powyższe zdarzenie nie zostanie zakończone.
Więc moje pytanie brzmi: co mogę z tym zrobić? Czy jest jakieś lepsze wydarzenie, w które mogę się wpakować, czy też jest inny sposób na to poradzić? Myślałem o rozpoczęciu zadania w tle, ale wydaje mi się, że to przesada.
EDYTOWAĆ:
Aby wyjaśnić skalę tego problemu, mówię o maksymalnie 3-4 sekundach braku odpowiedzi. To nie jest długa praca.
EDYTOWAĆ:
Próbowałem niektórych sugestii poniżej, jednak cały stos wywołań zSelectionChanged
funkcja korzysta z async / czeka. Śledziłem to do tego stwierdzenia:
myFeed = await client.RetrieveFeedAsync(uri);
Co wydaje się nie być kontynuowane, dopóki nie zostanie ukończone.
EDYTOWAĆ:
Zdaję sobie sprawę, że to przekształca się w War & Peace, ale poniżej jest replikacja problemu za pomocą pustej aplikacji metra i przycisku:
XAML:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<Button Click="Button_Click_1" Width="200" Height="200">test</Button>
<TextBlock x:Name="test"/>
</StackPanel>
</Grid>
Kod za:
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";
}
}