Saltar al contenido

Uso de Application.DoEvents ()

Solución:

Hmya, la perdurable mística de DoEvents (). Ha habido una enorme cantidad de reacciones violentas en su contra, pero nadie explica realmente por qué es “malo”. El mismo tipo de sabiduría que “no mutes una estructura”. Erm, ¿por qué el tiempo de ejecución y el lenguaje admiten la mutación de una estructura si eso es tan malo? La misma razón: te disparas en el pie si no lo haces bien. Fácilmente. Y hacerlo bien requiere saber exactamente lo que hace, que en el caso de DoEvents () definitivamente no es fácil de asimilar.

De buenas a primeras: casi todos los programas de Windows Forms contienen una llamada a DoEvents (). Está inteligentemente disfrazado, sin embargo con un nombre diferente: ShowDialog (). Es DoEvents () el que permite que un diálogo sea modal sin que congele el resto de las ventanas de la aplicación.

La mayoría de los programadores quieren usar DoEvents para evitar que su interfaz de usuario se congele cuando escriben su propio bucle modal. Ciertamente hace eso; envía mensajes de Windows y recibe cualquier solicitud de pintura. Sin embargo, el problema es que no es selectivo. No solo envía mensajes de pintura, también entrega todo lo demás.

Y hay un conjunto de notificaciones que causan problemas. Vienen desde aproximadamente 3 pies frente al monitor. El usuario podría, por ejemplo, cerrar la ventana principal mientras se ejecuta el bucle que llama a DoEvents (). Eso funciona, la interfaz de usuario se ha ido. Pero su código no se detuvo, todavía está ejecutando el ciclo. Eso es malo. Muy muy mal.

Hay más: el usuario puede hacer clic en el mismo elemento de menú o botón que hace que se inicie el mismo bucle. Ahora tiene dos bucles anidados ejecutando DoEvents (), el bucle anterior está suspendido y el nuevo bucle comienza desde cero. Eso podría funcionar, pero las probabilidades son escasas. Especialmente cuando el ciclo anidado termina y el suspendido se reanuda, tratando de terminar un trabajo que ya estaba terminado. Si eso no funciona con una excepción, entonces seguramente los datos están mezclados al infierno.

Volver a ShowDialog (). Ejecuta DoEvents (), pero tenga en cuenta que hace otra cosa. Eso desactiva todas las ventanas de la aplicación, que no sea el diálogo. Ahora que el problema de 3 pies está resuelto, el usuario no puede hacer nada para estropear la lógica. Se resuelven los modos de falla de cerrar la ventana y comenzar de nuevo el trabajo. O para decirlo de otra manera, no hay forma de que el usuario haga que su programa ejecute el código en un orden diferente. Se ejecutará de manera predecible, tal como lo hizo cuando probó su código. Hace que los diálogos sean extremadamente molestos; ¿Quién no odia tener un diálogo activo y no poder copiar y pegar algo desde otra ventana? Pero ese es el precio.

Que es lo que se necesita para utilizar DoEvents de forma segura en su código. Establecer la propiedad Enabled de todos sus formularios en false es una forma rápida y eficiente de evitar problemas. Por supuesto, a ningún programador le gusta hacer esto. Y no lo hace. Por eso no debería usar DoEvents (). Deberías usar hilos. A pesar de que te ofrecen un arsenal completo de formas de disparar tu pie de formas coloridas e inescrutables. Pero con la ventaja de que solo disparas tu propio pie; no permitirá (normalmente) que el usuario dispare el suyo.

Las próximas versiones de C # y VB.NET proporcionarán un arma diferente con las nuevas palabras clave await y async. Inspirado en pequeña parte por los problemas causados ​​por DoEvents y subprocesos, pero en gran parte por el diseño de API de WinRT que requiere para mantener su interfaz de usuario actualizada mientras se lleva a cabo una operación asincrónica. Como leer de un archivo.

Puede ser, pero es un truco.

Ver ¿Es malo DoEvents?.

Directamente desde la página de MSDN a la que hizo referencia el desarrollador:

Llamar a este método hace que el hilo actual se suspenda mientras se procesan todos los mensajes de la ventana de espera. Si un mensaje provoca la activación de un evento, es posible que se ejecuten otras áreas del código de su aplicación. Esto puede hacer que su aplicación muestre comportamientos inesperados que son difíciles de depurar. Si realiza operaciones o cálculos que llevan mucho tiempo, a menudo es preferible realizar esas operaciones en un nuevo hilo. Para obtener más información sobre la programación asincrónica, consulte Descripción general de la programación asincrónica.

Entonces Microsoft advierte contra su uso.

Además, lo considero un truco porque su comportamiento es impredecible y propenso a efectos secundarios (esto proviene de la experiencia al intentar usar DoEvents en lugar de hacer girar un nuevo hilo o usar un trabajador en segundo plano).

Aquí no hay machismo; si funcionara como una solución sólida, estaría por encima de todo. Sin embargo, intentar usar DoEvents en .NET no me ha causado más que dolor.

Sí, hay un método DoEvents estático en la clase Application en el espacio de nombres System.Windows.Forms. System.Windows.Forms.Application.DoEvents () se puede utilizar para procesar los mensajes que esperan en la cola en el subproceso de la IU cuando se realiza una tarea de larga duración en el subproceso de la IU. Esto tiene la ventaja de hacer que la interfaz de usuario parezca más receptiva y no “bloqueada” mientras se ejecuta una tarea larga. Sin embargo, casi siempre esta NO es la mejor manera de hacer las cosas. Según Microsoft, llamar a DoEvents “… hace que el hilo actual se suspenda mientras se procesan todos los mensajes de la ventana de espera”. Si se desencadena un evento, existe la posibilidad de que se produzcan errores inesperados e intermitentes que son difíciles de rastrear. Si tiene una tarea extensa, es mucho mejor hacerlo en un hilo separado. La ejecución de tareas largas en un subproceso separado permite que se procesen sin interferir con la IU para que continúe ejecutándose sin problemas. Busque aquí más detalles.

A continuación, se muestra un ejemplo de cómo utilizar DoEvents; tenga en cuenta que Microsoft también proporciona una advertencia contra su uso.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *