2009-07-12 32 views

Respuesta

17

Application.DoEvents se usa generalmente para asegurarse de que los eventos se manejan periódicamente cuando se realiza una operación de larga ejecución en el hilo de la interfaz de usuario.

Una mejor solución es simplemente no hacer eso. Realice operaciones de larga ejecución en subprocesos independientes, clasificándose en el subproceso de interfaz de usuario (ya sea usando Control.BeginInvoke/Invoke o con BackgroundWorker) cuando necesite actualizar la interfaz de usuario.

Application.DoEvents introduce la posibilidad de reentrada, lo que puede conducir a errores muy difíciles de entender.

+0

Jon, dijiste que para asegurarte de que los eventos se manejan periódicamente ... ¿qué eventos? en una programación secuencial, supongamos que tenemos un botón en un formulario. cuando el usuario hace clic, por ejemplo, la opacidad del formulario cambia ... ahora, ¿qué tipo de eventos hay aquí excepto por el clic del botón? – odiseh

+0

Repinta, redimensiona, mueve el mouse, etc. Hay una gran cantidad de eventos, incluso si el código de su aplicación no maneja explícitamente la mayoría de ellos. –

+0

@JonSkeet Me encantaría su comentario sobre un posible uso válido de 'DoEvents'. https://stackoverflow.com/questions/45023826/is-this-a-valid-use-of-doevents-sample-project-included –

1

Imho es mejor que nunca lo use, ya que puede terminar con un comportamiento muy inesperado. El código recién generado está bien. Cosas como usted están ejecutando nuevamente el controlador de eventos en el que se encuentra actualmente, porque el usuario presionó una tecla dos veces, etc. Si desea actualizar un control para mostrar el proceso actual, debe llamar explícitamente .Update en ese control en lugar de llamar Application.DoEvents.

2

Windows mantiene una cola para contener varios eventos como hacer clic, cambiar tamaño, cerrar, etc. Mientras un control está respondiendo a un evento, todos los demás eventos se mantienen en la cola. Por lo tanto, si su aplicación demora demasiado en procesar un clic de botón, el resto de la aplicación parecerá congelarse. En consecuencia, es posible que su aplicación parezca no responder mientras realiza un procesamiento pesado en respuesta a un evento. Si bien lo ideal es hacer un procesamiento pesado de manera asincrónica para garantizar que la IU no se congele, una solución rápida y sencilla es simplemente llamar a Application.DoEvents() periódicamente para permitir que los eventos pendientes se envíen a su aplicación.

Para una buena aplicación de Windows, al usuario final no le gusta que cualquier forma de aplicación se congele mientras realiza una operación de mayor/mayor peso. El usuario siempre quiere que la aplicación se ejecute sin problemas y de manera receptiva en lugar de congelar la IU. Pero después de buscar en Google encontré que Application.DoEvents() no es una buena práctica para usar en aplicaciones con más frecuencia, por lo que en lugar de estos eventos, es mejor utilizar BackGround Worker Thread para realizar tareas largas sin tener que congelar ventanas.

Puede obtener una mejor idea si prácticamente lo mira. Simplemente copie el código siguiente y compruebe la aplicación con y sin poner Application.DoEvents().

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     For i As Integer = 0 To 1000 
      System.Threading.Thread.Sleep(100) 
      ListBox1.Items.Add(i.ToString()) 
      Application.DoEvents() 
     Next 
    End Sub 
Cuestiones relacionadas