2010-01-19 20 views
5

¿Tiene una buena solución para mantener una 'Por favor, espere' winform 'pintado' mientras una aplicación está ejecutando una tarea larga?Actualizaciones de Winform en tareas de larga ejecución

He intentado usar form.refresh() en cada paso, pero hay algunas consultas de ejecución larga que tienen lugar, lo que significa que esto no es lo suficientemente frecuente.

Básicamente este SO Question pero, en C# en Excel a través de VSTO (en lugar de Python).

+0

Es esto realmente formularios web, o se trata de winforms? Estás hablando de Excel y VSTO. y si se trata de formularios web, no tiene un método de actualización. –

+0

Lo sentimos, sí, Winforms, no Webforms .. He editado la pregunta ... Ha sido un día largo ... –

+0

¿Alguna solución final con el código fuente completo de la muestra? ¿Qué hay de usar el proceso de larga ejecución con los pasos usando C#, SignalR? – Kiquenet

Respuesta

1

Here's a good example con código en C#.

Es específicamente para pantallas de bienvenida, sin embargo, es un proceso casi idéntico (quizás menos parte de la llamativa Opacidad) para crear una ventana Espere por favor.

La información clave es que necesitará un hilo por separado. Esto puede complicar las cosas, sin embargo, el artículo ofrece una buena cobertura/ejemplo de cómo hacerlo correctamente.

+0

Gracias por este enlace. Funciona muy bien y se integra muy bien en mi aplicación Excel VSTO. –

1

Utilice un BackgroundWorker

+0

Hombre, estoy cansado, pensé que esto era winforms. La respuesta debería ser usar AJAX (MS AJAX funcionará bien). Puede usar un control Timer para verificar el estado. Entonces puedes redirigir al finalizar. – hackerhasid

+0

Enlace de MSDN: http://msdn.microsoft.com/en-us/magazine/cc164051.aspx – hackerhasid

+0

Disculpe, la pregunta se cambió de webforms => winforms. –

0

Otra opción es usar un delegado asíncrono para mostrar el formulario en una cadena de subprocesos.

Los subprocesos en el grupo de subprocesos se recomiendan para subprocesos de vida más corta que no duran toda la duración de la aplicación. Como se trata de mostrar una ventana de espera de corta duración, el grupo de subprocesos es una opción razonable.

El delegado de acción (.NET 2.0+) se utiliza junto con su método BeginInvoke() para ejecutar automáticamente el código de delegado en una secuencia de subprocesos.

Algunas notas:

  • Es importante utilizar Control.BeginInvoke para cualquier llamada GUI hilo cruzado, tales como cerrar el formulario por favor espere en ClosePleaseWait().
  • Además, el m_pleaseWaitForm.ShowDialog(); realmente inicia un nuevo bucle de mensaje en el nuevo hilo. Esto es lo que mantiene vivo el formulario de espera por favor.
  • Como se utiliza un hilo de subprocesos, este subproceso se convierte automáticamente en un subproceso en segundo plano y finalizará si la aplicación principal está cerrada.
  • Además de ejecutar en otro hilo, no hay nada especial acerca de Form2. Puede colocar controles secundarios como Pictureboxes, etiquetas, etc.
  • (MethodInvoker)delegate { ... } es solo una forma .NET 2.0 de ejecutar código en un delegado en línea.

El siguiente ejemplo se puede agregar a un proyecto de WinForms que contiene Form1: el formulario principal, y Form2: el formulario de espera por favor.

private Form2 m_pleaseWaitForm = null; 

    private void Form1_Shown(object sender, EventArgs e) 
    { 
     // This code could also be placed in eg. a button click event handler. 

     Action<Rectangle> a = new Action<Rectangle>(ShowPleaseWait); 

     a.BeginInvoke(this.Bounds, null, null); 

     // Do your long running tasks 

     ClosePleaseWait(); 
    } 


    private void ShowPleaseWait(Rectangle bounds) 
    { 
     // This method runs on the new thread. 

     m_pleaseWaitForm = new Form2(); 

     m_pleaseWaitForm.TopMost = true; 
     m_pleaseWaitForm.Location = new Point(bounds.Left + bounds.Width/2 - m_pleaseWaitForm.Width/2, bounds.Top + bounds.Height/2 - m_pleaseWaitForm.Height/2); 

     m_pleaseWaitForm.ShowDialog(); 

    } 

    private void ClosePleaseWait() 
    { 
     m_pleaseWaitForm.BeginInvoke((MethodInvoker)delegate { m_pleaseWaitForm.Close(); }); 
    } 
3

Como mencioné en statichippo, utilizaría la clase BackgroundWorker. Su propósito es simplificar el multihilo y permitir que un hilo de trabajo haga el proceso que consume mucho tiempo sin bloquear la GUI.

Aquí es una cita de MSDN:

La clase BackgroundWorker permite a ejecutar una operación en un hilo separado, dedicado.Las operaciones como y las descargas que consumen tiempo pueden hacer que su usuario interfaz (IU) parezca haya dejado de responder mientras están ejecutando . Cuando desee una interfaz de usuario receptiva y tenga que enfrentarse a largas demoras asociadas con dichas operaciones, la clase BackgroundWorker brinda una solución conveniente .

Aquí es un buen tutorial de cómo utilizar la clase BackgroundWorker en formas de las ventanas: Implementing multi-threading in WinForms using the BackgroundWorker class

Hay formas más complicadas de implementar Multi-Threading en C# para escenarios complejos, pero para los escenarios más simples del BackgroundWorker grandes obras (al menos para mí).

Estos son algunos enlaces que sacó de Google en C# múltiples subprocesos:
MSDN Threading
Introduction to Multithreading in C#

+0

cualquier muestra de código fuente completo? – Kiquenet

Cuestiones relacionadas