2011-05-08 3 views
1

Quelqu'un peut-il m'expliquer pourquoi le style ci-dessous appliqué à un Silverlight ListBox lié à une collection de 2000 éléments fuit la mémoire comme fou tout en faisant défiler la liste? L'utilisation de la mémoire va très rapidement dans les centaines de mégaoctets.Silverlight DataTemplate Memory Leak

La fuite ne se produit que si je laisse l'élément ItemsControl. Sinon, la consommation de mémoire reste active. La fuite ne se produit pas non plus si la propriété "Tags" (Type: string []) que la variable ItemsControl est liée renvoie un tableau readonly statique de son getter.

Ceci est la mise en œuvre de la propriété "Tags" getter et j'ai essayé d'appeler les getters d'une liste éléments dans une boucle serait également une fuite, mais ce n'est pas le cas. Nous parlons de 1-5 Tags par Collection Item = 10000 Strings au maximum. Il semble que la fuite se produit uniquement si ItemsControl est lié à une collection non statique.

La version d'exécution est 4.0.60310.0 AFAIK est supérieur à celui qui est censé réparer le DataLemplate MemoryLeak.

<Style x:Key="DocumentHybridListBox" TargetType="ListBox"> 
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> 
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="BorderThickness" Value="1"/> 
    <Setter Property="Padding" Value="3"/> 
    <Setter Property="ItemsPanel"> 
     <Setter.Value> 
      <ItemsPanelTemplate> 
       <VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling" Orientation="Vertical" Margin="1, 3, 1, 3" /> 
      </ItemsPanelTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="ItemTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*"/> 
        </Grid.ColumnDefinitions> 
        <Image Grid.Column="0" Style="{StaticResource DocumentList_Hybrid_Image}"> 
         <Image.Source> 
          <BitmapImage Behaviors:BindableBitmapImageSource.Source="{Binding PreviewPicture}"></BitmapImage> 
         </Image.Source> 
        </Image> 
        <Grid Grid.Column="1" Margin="6, 0, 0, 0"> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"></RowDefinition> 
          <RowDefinition Height="Auto"></RowDefinition> 
          <RowDefinition Height="Auto"></RowDefinition> 
         </Grid.RowDefinitions> 
         <TextBlock Grid.Row="0" Text="{Binding Summary}" FontWeight="Bold" TextTrimming="WordEllipsis"></TextBlock> 
         <TextBlock Grid.Row="2" Text="{Binding DateSummary}" FontSize="11" TextTrimming="WordEllipsis"></TextBlock> 

         <!--- Problem starts here --> 
         <ItemsControl Grid.Row="1" ItemsSource="{Binding Tags}" Margin="0, 3, 0, 3"> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <StackPanel Orientation="Horizontal"></StackPanel> 
           </ItemsPanelTemplate> 
          </ItemsControl.ItemsPanel> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 
            <Button Content="{Binding}" Style="{StaticResource TagButton}" 
             Command="{Binding DataContext.TagDrillDownCmd, ElementName=Self}" 
             CommandParameter="{Binding}" 
             ToolTipService.ToolTip="{Binding Converter={StaticResource tagTooltipConverter}}"></Button> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ItemsControl> 
        </Grid> 
       </Grid> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

La propriété Tags:

private string[] _tags = null; 
static readonly string[] constTags = new [] { "foo", "bar "}; 

public string[] Tags 
{ 
    get 
    { 
     //return constTags; // this won't leak if bound to ItemsControl 
     if (_tags == null) 
     { 
      // initialize 
      if (Document.Tags != null && Document.Tags.Length != 0) 
      { 
       // initialize 
       _tags = Document.Tags.Select(t => Decrypt2String(t, 
        ServiceLocator.Get<IKeyContainer>().DerivedContentEncryptionKey)).ToArray(); 
      } 
     } 

     return _tags; 
    } 

    set 
    { 
     _tags = value; 
     OnPropertyChanged(()=>Tags); 
    } 
} 

Répondre

0

Il y a un problème connu dans les modèles de données Silverlight liées Leake mémoire. Il a été autour depuis un certain temps. Vérifiez this lien

+1

Je connais ce fil. Mais au moins les fuites liées à DataTemplate sont censées être corrigées avec un correctif il y a un certain temps. –