2009-02-20 9 views
26

¿Cuál es la mejor manera de actualizar una etiqueta en una aplicación de Windows Forms durante el proceso?Etiqueta de actualización durante el procesamiento en Windows Forms

que tienen un bucle que hace algún tipo de procesamiento de archivos en el sistema del usuario cuando el usuario hace clic en un botón.

foreach (System.IO.FileInfo f in dir.GetFiles("*.txt")) 
{ 
    // Do processing 
    // Show progress bar 
    // Update Label on Form, "f.Name is done processing, now processing..." 
} 

¿Qué código de muestra hay?

¿Cómo se llama exactamente? ¿Está enhebrando o delegados?

Respuesta

48

Una solución rápida para usted sería:

Label1.Text = f.Name + " is done processing, now processing..."; 
Label1.Refresh(); 

que realmente quiere evitar DoEvents, de lo contrario tendrá problemas si el usuario presiona los botones repetidamente en su formulario.

13

Usted debe estar haciendo esto en otro hilo, y luego actualizar el hilo de interfaz de usuario de ese hilo. Está bloqueando el procesamiento posterior realizando este trabajo en el subproceso de interfaz de usuario.

Si no puede mover este código para el hilo de interfaz de usuario, entonces se podría llamar siempre a Application.DoEvents, pero fuertemente sugerir a explorar estas opciones primero:

+1

Estoy de acuerdo con esto, especialmente para BackgroundWorker. Lo uso con frecuencia yo mismo.¡BackgroundWorkers hace que las operaciones de subprocesamiento múltiple como esta sean simples y fáciles! – Keithius

13

Tendrá que obtener los datos de un subproceso a la otra. Esto se puede hacer en un par de maneras ...

En primer lugar, el hilo "fondo" podría actualizar algún tipo de "CurrentStatus" variable de cadena que cambia a medida que avanza. Luego podría poner un temporizador en su formulario que luego tomaría la variable CurrentStatus y actualizaría la etiqueta con ella.

segundo lugar, usted podría simplemente invocar la operación desde el subproceso de fondo para el hilo de interfaz de usuario con un delegado utilizando la propiedad InvokeRequired del control de etiqueta. Así, por ejemplo ...

private delegate void UpdateStatusDelegate(string status); 
private void UpdateStatus(string status) 
{ 
    if (this.label1.InvokeRequired) 
    { 
     this.Invoke(new UpdateStatusDelegate(this.UpdateStatus), new object[] { status }); 
     return; 
    } 

    this.label1.Text = status; 
} 

Usted puede llamar a este método desde cualquier hilo (IU o de fondo) UpdateStatus(), y detectará si es o no necesita invocar la operación en el hilo principal interfaz de usuario (y si es así, ¿verdad?)

Para establecer realmente el hilo, puede hacerlo de esta manera:

private void StartProcessing() 
    { 
     System.Threading.Thread procThread = new System.Threading.Thread(this.Process); 

     procThread.Start(); 
    } 

    private void Process() // This is the actual method of the thread 
    { 
     foreach (System.IO.FileInfo f in dir.GetFiles("*.txt")) 
     { 
      // Do processing 
      // Show progress bar 
      // Update Label on Form, "f.Name is done processing, now processing..." 
      UpdateStatus("Processing " + f.Name + "...");     
     } 
    } 

Luego, cuando el usuario hace clic en el botón "IR" se le llama simplemente StartProcessing().

+1

Debe ser la respuesta perfecta. –

Cuestiones relacionadas