2010-08-04 12 views
5

Estoy tratando de utilizar un trabajador de fondo para recuperar una gran cantidad de datos de la base de datos sin detener el hilo principal. Esto parece funcionar bien, excepto que cuando se trata de actualizar la interfaz de usuario, la actualización congela la pantalla. código correspondiente de la siguiente manera:C# Actualización UI de trabajador de fondo

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    {    
     lvwTest.BeginUpdate(); 
     lvwTest.Items.Clear(); 

     // Populate the UI 
     foreach (TestItem ti in testData) 
     { 
      ListViewItem lvi = lvwTest.Items.Add(ti.Value1); 
      lvi.SubItems.Add(ti.Value2); 
     } 

     lvwTest.EndUpdate();      
    } 

La actualización tarda alrededor de 2 - 3 segundos, para los que el tiempo se cerró la pantalla. Me doy cuenta de que solo el hilo principal puede actualizar la pantalla, pero ¿es posible cargar estos datos en la memoria de alguna manera (en un hilo de fondo u otra instancia de una vista de lista o algo así) y luego simplemente mostrarlo? Todo lo que quiero que suceda es que el programa simplemente actualice los datos sin perder tiempo en el hilo principal.

Respuesta

1

Recomiendo cargar los datos en la memoria y usando un modo virtual ListView. De esta forma, solo creará los objetos ListViewItem a medida que se necesiten.

1

Si tiene que cargar una gran cantidad de datos en la interfaz de usuario, necesitará tiempo y bloqueará nuestra aplicación. La opción es desplazamiento inteligente o paginación. Cargas todos los datos pero los pones uno por uno a petición del usuario.

0

Además de la virtualización, recomendaría dividir los artículos en lotes de, digamos, 100 y agregar cada lote en su propio mensaje. De esta forma, la UI tiene un cambio para procesar otros mensajes mientras los lotes se agregan al ListView.

En otras palabras, todo el controlador RunWorkerCompleted hace cola el primer lote para agregar en un mensaje separado. El método de adición agregará los elementos y luego pondrá en cola el siguiente lote. Esto continuará hasta que no queden más elementos para agregar. En ese momento, volvería a habilitar la parte relevante de su UI (ListView).

0

Dado que la mayoría de los anteriores son buenos consejos, pero realmente no resuelven su problema inmediato, este es otro enfoque: Esto actualizará su GUI y la mantendrá receptiva. ¿Asumiendo que estás en la aplicación WinForm?

 Application.DoEvents(); 
     this.Refresh(); 

Sin embargo, esto no quiere decir que tal vez no debe escuchar a las ideas desde arriba :-)

+0

Es una aplicación WinForm - pero en los días de VB6, DoEvents estaba mal visto, ya que podría cambiar la secuencia de eventos. ¿No es ese el caso en C#? –

+0

Puede que tengas razón, sigue siendo un poco complicado por lo que he escuchado. Depende de la complejidad de su aplicación. He reescrito mi última aplicación simple para WPF, que en realidad es un Framework realmente bueno. – Remy

Cuestiones relacionadas