Pregunta

Estoy creando una aplicación wpf utilizando MVVM. Tengo viewModels the use perzy loading como abajo:

public class AssignmentsViewModel
{

    List<AssignmentViewModel> _Assignments;
    public List<AssignmentViewModel> Assignments
    {
        get
        {
            if (_Assignments == null)
                _Assignments = new List<AssignmentViewModel>(Data.GetAssignments());
            return _Assignments;
        }
        set { _Assignments = value; }
    }
}
public class AssignmentViewModel
{
    List<NoteViewModel> _Notes;
    public List<NoteViewModel> Notes
    {
        get
        {
            if (_Notes == null)
                _Notes = new List<NoteViewModel>(Data.GetNotes());
            return _Notes;
        }
        set { _Notes = value; }
    }
}

La vista tiene los modelos AssignmentView en un ListView y las notas en un ListBox con una placa de datos.

Cuando muestro uno de los AssignmentViewModels que tiene 160 elementos, demora 1000 ms en cargarse. Pensé que era debido a que la propiedad de Notes se tomaba de una tabla de base de datos con 1.5 millones de filas. Lo verifiqué y solo tomó 60 ms para completar la lista de Notas. Así que supongo que es el enlace de datos de cargar los 160 elementos en el cuadro de lista. Pero ese no debería ser el caso porque los listBox virtualizan su contenido (lo busqué y verifiqué que los elementos están en un panel de apilamiento de virtualización).

Así que estoy perdido, no sé cómo averiguar qué está tomando los 940 ms adicionales.

¿Qué puedo hacer para rastrear esto? El rendimiento es clave, y no sé cómo mejorarlo.

¿Fue útil?

Solución

Sin saber cómo es la interfaz de usuario, existe la posibilidad de que algo de la interfaz de usuario la esté ralentizando como un gran uso de BitmapEffects.

Además, es posible que desee cambiar su lista a ObservableCollection, como vincular a eso puede ser significativamente más rápido que una lista .

También hay algunas buenas perfiles de rendimiento que pueden ayudar usted.

Otros consejos

¿Podríamos ver tu XAML?

Si tiene su cuadro de lista dentro de un panel de apilamiento (o un control similar), el cuadro de lista no virtualizará sus entradas.

Esto se virtualizará:

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Label Grid.Row=0>Your label here</Label>
  <ListBox Grid.Row=1 Your properties here... />

</Grid>

Esto no:

<StackPanel>
  <Label>Your label here</Label>
  <ListBox Your properties here... />
</StackPanel>

Dentro del panel de apilamiento, el cuadro de lista se representará a su altura máxima y dependerá del panel de apilamiento para el desplazamiento. (Sin virtualización)

Dentro de la cuadrícula, el cuadro de lista se representará a la altura de la fila de la cuadrícula y usará su propio visor de desplazamiento. (Virtualizando)

También puedes configurar las propiedades Height o MaxHeight en el cuadro de lista en lugar de colocarlas dentro de una cuadrícula, pero si estás usando un panel de la pila, sospecho que quieres un autoajuste de algún tipo.

Tenga en cuenta que no puede hacer trampa colocando el panel de la pila dentro de la cuadrícula; su cuadro de lista tiene que ser capaz de derivar una altura máxima de algún lugar.

¿Has probado las pruebas de rendimiento sin carga lenta?

Además, ¿qué tan complicadas son sus Plantillas / Vistas de datos para sus artículos? Intente ejecutar una prueba con simples representaciones de TextBlock para asegurarse de que no sea lo complicadas que son sus vistas.

Volvería a analizar el SQL y me aseguraré de que tu colección se esté llenando. L2S no se completará hasta que enumere el resultado.

private IEnumerable<Thing> Method1()
{
    return _db.Things.Where(t => t.ID > 500);
}
private void Method2()
{
    var things = Method1(); // here, 'things' doesn't really contain anything
                            // even though you've already done the db fetch
    foreach (var thing in things) // 'things' gets populated here.
    {
        // do something
    }
}

ej: llame a .ToList () inmediatamente después de que se devuelvan los datos. Verá mucha más actividad en el nivel de datos que puede que no haya ocurrido hasta su negocio o la capa de UI.

Lo descubrí. Tuve un bloque de texto que necesitaba ajuste de texto porque a veces es bastante grande. Establecí explícitamente el ancho de la misma (para que se ajustara) dentro de la placa de datos y, por alguna razón, eso hace que VirtualizingStackPanel dentro de ListBox realice todos los elementos de la lista. Lo reelaboré para encajarlo en una cuadrícula como tal ...

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
       ....
    </Grid>
    <ListBox Grid.Column="1" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
       ...//DataTemplate
    </ListBox>
</Grid>

Esto hizo que el cuadro de lista se cargara rápidamente. Gracias por las respuestas que me trajeron en el camino correcto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top