LongListSelector: низкая производительность из-за предварительной загрузки

#c# #performance #xaml #windows-phone-8 #longlistselector

#c# #Производительность #xaml #windows-phone-8 #longlistselector

Вопрос:

Я хочу выпустить приложение и протестировать его с помощью Store-Test-kit. Одно из моих сводных представлений содержит что-то вроде новостной страницы, на которую всегда поступает 30 новостных элементов с сервера. На моем экране есть место примерно для 5 новостей, но все равно он предварительно загружает 17-18 и зависает из-за этого. Я тестирую его с помощью слушателей ItemRealized / ItemUnrealized.

Довольно глупо, что из-за автоматического поведения тестовый набор говорит мне, что это моя вина, что у приложения такая плохая отзывчивость D:

Есть ли способ заставить его загружать меньше новостей? Если я увеличу 1 новость на 400 пикселей, она загрузит 5-6 из них и не зависнет. Конечно, добавление пробелов — не лучшее решение =/

И да: в моих новостях есть изображение с ними. Но когда я это комментирую, он все еще зависает. 18 новостей — это слишком много для загрузки сразу.

Редактировать:

Я получаю данные асинхронно и привязываю их. Файл .xaml:

 <phone:LongListSelector x:Name="NewsSelector" LayoutMode="List" IsGroupingEnabled="False" ItemsSource="{Binding OnlineNews}" SelectionChanged="News_LongListSelector_SelectionChanged">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <Grid VerticalAlignment="Top" HorizontalAlignment="Left" >
                <!--...-->
                <Image Source="{Binding TeaserImage}" Width="120" Height="120" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.RowSpan="3" />
                <StackPanel Grid.Column="1" Margin="6,0,0,0">
                    <TextBlock Text="{Binding Title}" TextWrapping="Wrap" MaxHeight="54" TextTrimming="WordEllipsis" Style="{StaticResource PhoneTextAccentStyle}" FontFamily="Verdana" FontSize="22" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                    <TextBlock Text="{Binding TeaserText}" TextWrapping="Wrap" MaxHeight="44" TextTrimming="WordEllipsis" Style="{StaticResource PhoneTextTitle3Style}" FontFamily="Verdana" FontSize="18" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                    <TextBlock Text="{Binding PubDate}" Margin="12,4,0,4" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="Verdana" FontSize="18" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
  

и ViewModel .cs:

 public void LoadNewsPage()
{
    this.IsLoadingNews = true;
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(NEWS_URL));
    request.BeginGetResponse(new AsyncCallback(NewsCallback), request);
}

private void NewsCallback(IAsyncResult asynchronousResult)
{
    try
    {
        //...
        foreach (var d in list.news)
        {
            //...
            OnlineNews.Add(new OnlineNewsViewModel() {
                //...
            });
        }
    }
    catch
    {
        //...
    }
}
  

Но не имеет значения, откуда я беру данные. Он также заикается, когда я жду на другой странице, пока не будут загружены все новости, а затем переключаюсь -> создаю 18 новостей с 1 изображением и 3 текстовыми блоками -> зависает.
На Lumia 1320 это лучше с большей производительностью. Но у меня нет возможности запустить это на Lumia 520 без сбоев..

Комментарии:

1. вы заполняете его асинхронно?

Ответ №1:

Обязательно настройте изображение для фоновой загрузки следующим образом:

 <Image Height="100" Width="100" Margin="12,0,9,0">
  <Image.Source>
    <BitmapImage UriSource="{Binding ImgURL}" CreateOptions="BackgroundCreation"/>
  </Image.Source>
</Image>
  

Комментарии:

1. Не знал этого! Это помогает, но все равно зависает, даже если я полностью отключу изображение. Являются ли 3 текстовых блока с пользовательским шрифтом слишком большими для элемента LLS?

2. Нет, очень странно. Другим вариантом является выполнение работы по загрузке потока пользовательского интерфейса с помощью Task.Run(() => …) и добавление каждого новостного элемента с помощью Deployment . Текущий. Диспетчер. BeginInvoke(() => …)

3. Тоже думал об этом. Добавляйте к нему только несколько элементов и добавляйте больше к ItemRealized один за другим, как вы сказали. Но это была бы ручная обработка .. ^^

4. Хороший шаблонный пример можно найти здесь взгляните на метод private async Task<TReturnType> GetResponse<TReturnType>!

5. Я использую это в методе RefreshLayout follwit.codeplex.com/SourceControl /… обратите внимание, что теперь я вижу, что забыл использовать диспетчер, поэтому this this.Movies. Добавление (movie) должно быть Deployment. Текущий. Диспетчер. BeginInvoke(() => this.Movies. Добавить (фильм))