vb6 doevents

¿Qué hace "DoEvents" en vb6?



doevents access (4)

¿Qué hace "DoEvents" en vb6? ¿Por qué aparece el mensaje de error "Sin espacio en la pila"? Qué significa eso ?


Aclararía la respuesta de Johnathon, ya que bombea el bucle de mensajes de VB y permite que VB Runtime procese los mensajes de Windows, que es lo opuesto a Sleep, que permite que Windows procese sus eventos (no es necesario en el mundo de las CPUs multinúcleo y los verdaderos sistemas operativos multitarea). pero cuando se escribió VB6, Windows 9x era el sistema operativo dominante y un bucle duro que solo tenía DoEvents aumentaría el uso de la CPU al 100%. Así que viendo cosas como

While fDoneFile = False DoEvents Sleep 55 Wend

Fue un patrón común en todo el mundo VB6.


Como se indica en otro lugar, DoEvents permite que se activen otros eventos en su aplicación. Este es un ejemplo de cómo puede usar DoEvents sin el problema "Sin espacio en la pila". Esto garantiza que no ejecute el código varias veces utilizando un booleano para indicar que el código se está ejecutando.

Sub Example() ''Create static variable to indicate the sub is running. Static isRunning As Boolean ''Exit the sub if isRunning If isRunning Then Exit Sub ''Indicate sub is running isRunning = True ''Sub does stuff DoEvents ''Ends up calling sub again Example ''Added just to prove via testing. ''Indicate sub is no longer runningrunning isRunning = False End Sub


DoEvents () permite procesar otros mensajes de Windows.

La razón por la que se produce un error de falta de espacio en la pila es probablemente porque DoEvents () permite que ocurran eventos que vuelvan a llamar a su código, lo que nuevamente se llama a DoEvents (), y así sucesivamente hasta el espacio de la pila, que rastrea las direcciones de retorno de todos estos llama, se ha acabado.

En general, no recomiendo usar DoEvents () debido a problemas como estos y al hecho de que viola el diseño general de Windows basado en eventos.


Una forma ligeramente diferente de ver DoEvents es que vacía los eventos en la cola de eventos. Si su sub o función activa un evento, ese controlador de eventos se convierte en un sub que está en línea para ejecutarse tan pronto como finalice su sub / función. DoEvents le dice que ejecute ese controlador de eventos sub ahora, en lugar de esperar hasta el final de su sub.

Si bien estoy de acuerdo con Jonathon sobre no usar DoEvents, templaría su afirmación diciendo que solo recomiendo usarla si sabe exactamente por qué, y conocer todas las repercusiones de cambiar el orden de la cola de eventos de esta manera. La mayoría de las veces, DoEvents se indica cuando desea actualizar su pantalla de alguna manera desde el contexto de una subrutina, antes de que la subrutina termine de ejecutarse.

Un ejemplo de esto es cuando está utilizando el control ProgressBar. Supongamos que está recorriendo varios miles de registros y desea proporcionar comentarios al usuario sobre su progreso actualizando una barra de progreso. Podría interrumpir su ciclo cada cien registros y cambiar el valor en el control de la barra de progreso. Sin embargo (a menos que haga algo al respecto), no verá el cambio en la pantalla hasta después de que se ejecute el controlador de eventos de cambio de la barra de progreso, y ese controlador no se ejecutará hasta que se termine la ejecución del subwoofer. Simplemente se pondrá en la cola de eventos. La forma de forzar el evento de cambio para que se ejecute inmediatamente, suspendiendo su sub, es llamar a DoEvents. Esto eliminará todos los eventos existentes de la cola (en este caso, el evento de cambio de la barra de progreso) y actualizará el control de la barra de progreso en la pantalla.

Ahora, "sin espacio en la pila" básicamente significa que has estado atrapado en un bucle sin fin de llamadas a funciones. La forma más básica de hacer esto es esta:

Public sub MySub() MySub End Sub

Y luego llamar a MySub desde algún lugar. Obtendrá un error de espacio de pila. Si observas la pila de llamadas, verás una línea muy larga de llamadas a MySub.

Un ejemplo real conocido de esto sucedería en versiones anteriores de VB:

Public Sub TextBoxArray_LostFocus(index as Integer) If TextBoxArray(index) = "" Then TextBoxArray(index).SetFocus MsgBox "Please enter a value" End If End Sub

Esta situación asume dos miembros de una matriz de control TextBox llamada TextBoxArray. Ahora, si el usuario comienza con el primero (índice 0) y se mueve hacia el segundo (índice 1), se activará el evento LostFocus del índice 0. Sin embargo, VB también establecería internamente el foco en el cuadro del índice 1. Luego, el código volvería a establecer el enfoque en el índice 0, ¡activando el evento LostFocus del índice 1! Estás atrapado en un bucle. Lo arreglaron en VB5 o 6 al esperar para establecer el enfoque hasta que se ejecutó el evento LostFocus.