【问题标题】:Performance issues when populating datagrid during deserialization在反序列化期间填充数据网格时的性能问题
【发布时间】:2020-06-25 09:28:56
【问题描述】:

我们的数据网格大约有 50 行和 30 列。所有列都是带有自定义单元格样式的模板列,我们使用的是材料设计样式。大多数列的模板与下面的相同,但绑定到不同的属性。

<DataGridTemplateColumn>    
     <DataGridTemplateColumn.HeaderTemplate>
           <DataTemplate>
                <TextBlock TextWrapping="Wrap" Width="60" Text="Time-Column"/>
           </DataTemplate>
     </DataGridTemplateColumn.HeaderTemplate>
     <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
               <Border 
                       BorderThickness="0,0,0,0"
                       VerticalAlignment="Center"
                       CornerRadius="3"
                       MinHeight="{Binding Source={x:Static properties:Settings.Default}, Path=TestHeight}>
                                                   
               <Grid>
                    <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                    <RowDefinition Height="*"></RowDefinition>
                    <RowDefinition Height="3*"></RowDefinition>
                    </Grid.RowDefinitions>
                    <Ellipse Grid.Row="0" HorizontalAlignment="Left" 
                             Margin="2,1,0,0" IsHitTestVisible="False" Visibility="{Binding 
                       TimeCell.IsChangedVisibility,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" 
                       Width="5"  
                       Height="5"  
                       Fill="Cyan"  
                       Panel.ZIndex="100"/>

                  <TextBox Style="{StaticResource MaterialDesignTextBox}" 
                    GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus" TabIndex="0" 
                    MinHeight="{Binding Source={x:Static properties:Settings.Default}, Path=TestRow}" 
                    VerticalContentAlignment="Bottom" Width="65"  HorizontalAlignment="Left" 
                    Grid.Column="0" Grid.ColumnSpan="2"  Grid.Row="1" Grid.RowSpan="2" 
                    VerticalAlignment="Bottom" TextChanged="TextBox_TextChanged" 
                    SelectionChanged="TextBox_SelectionChanged"  
                    Text="{Binding TimeCell.DisplayText2, 
                    UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,ValidatesOnDataErrors=True}">
                  </TextBox>

                  <Label IsHitTestVisible="False" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" FontSize="10" Content="{Binding TimeCell.Unit, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"></Label>
                 
                  <TextBlock Focusable="False" Text="{Binding TimeCell.CellBadge.Text, 
                   Mode=OneWay,UpdateSourceTrigger=PropertyChanged,TargetNullValue=''}"
                   HorizontalAlignment="Right"  FontSize="9" FontWeight="SemiBold" 
                   Foreground="#db4848" Margin="0,-1,2,0" Grid.Column="0" Grid.ColumnSpan="2" 
                   Grid.Row="0" IsHitTestVisible="False">
                  </TextBlock>

             </Grid>

             </Border>

        </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

启动程序时,加载数据网格大约需要 4-5 秒。当尝试加载另一个文件/集合并设置 datacontext 时,大约需要 4-5 秒,每次加载增加 50 MB 内存。 我尝试减少列的数量,一切都变得更快了,但延迟和 RAM 增加(20mb 而不是 50mb)仍然存在。行和列虚拟化已启用。

我们使用 BinaryFormatter 作为我们的序列化器/反序列化器。

我们如何在填充和加载/启动时获得平滑且无延迟的布局?

【问题讨论】:

  • 您是否尝试过分析您的应用程序?什么方法导致延迟?
  • 我建议您尝试将步骤分开并在每个步骤上放一个秒表。显示你的窗口。获取您的数据。将其呈现给数据网格。测量和安排可能相当昂贵。尝试将列宽设置为固定数字,看看有什么效果。为什么每次负载又增加了 50 兆克?二进制序列化通常是要避免的。您不能稍后再添加一列。
  • 似乎没有特别的方法会导致任何滞后,而是布局。不太确定这对我们意味着什么。我们应该对尺寸进行更多的硬编码吗?或者按百分比调整它们的大小?安迪,谢谢你,会的。正如我已经写过的,布局似乎是罪魁祸首。我不知道为什么每次加载还要 50 mb,这就是我们想要弄清楚的。另一种序列化方法是另一个好主意。
  • 在二进制序列化值得缺点之前,您需要大量数据。首选应该始终是字符串。方式更灵活。有 xml 或 json 的参数。看着你的模板。使其固定高度和宽度。如果你这样做,那么每个单元格只有一个措施安排通过。否则还有很多。也许是细胞数的平方。每个人都说我在加载时想要 n 宽度。然后布局说......我还有什么。你想要什么 col 2...嗯... col 3...hmmm.. col 4 怎么样?等等。然后是下一行。哦...第 3 列中的这个更宽...

标签: c# wpf performance xaml serialization


【解决方案1】:

如果可能的话,最好为所有列和行设置固定的宽度和高度。这可以是 * 度量值,也可以是其他度量值,例如 px。只要不是自动的。

如果您改为使用自动调整大小,则所有单元格都需要它们的宽度(可能还有高度),那么在容器知道任何给定列的宽度之前,必须考虑列中每个要求的大小。这可能会增加大量开销。

使用高度可能变化的模板对行进行自动高度同样会为每行提供大量布局计算。

另一种减慢速度的好方法是,如果您的列不完全适合。然后控制必须决定该截止点在哪里。这可能会使数据网格滚动非常慢。

如果你想加快速度。

考虑一个列表视图。它们本质上比数据网格更简单。

通过计算绝对宽度或使用比例(基于*)宽度和高度来减少测量安排。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多