The DoEvents() method is well known and available in VB 6.0 and VB.NET. Its often used in longer running, processor intensive code. It tells Windows to process the messages in the program’s message queue. That can help keep your program from appearing frozen and allows user interaction while the CPU is still busy executing the high usage code.
(In VB 6.0 and Older DoEvents() is a Function | In .NET and Newer its a Subroutine)
Unfortunately there is a tradeoff when using DoEvents. That tradeoff is ‘Performance’. The more you call DoEvents, the more CPU cycles are taken away from your intensive code to process the message queue. Thankfully, there is a way to help offset much of the performance loss and still allow your program to be responsive. That’s by using the GetInputState() function in the User32.dll library.
Most of the code in this article is from an example I made at www.vbcodesource.com.
It runs 3 different scenarios with benchmark data for each of them.
Scenario One: is executing a CPU intensive loop Without using DoEvents().
Scenario Two: is executing the loop using DoEvents() with the GetInputState() API call.
Scenario Three: is executing the loop using Only the DoEvents() method.
Windows API to the Rescue
What’s nice about the GetInputState() function is you can use it to First Check if there are any messages in the calling thread’s queue that is waiting to be processed. Below is the declare for that function…
Visual Basic 6.0
' 'This call will see whether or not there are any messages waiting 'to be executed in the calling thread. Private Declare Function GetInputState Lib "user32" () As Long
' 'This call will see whether or not there are any messages waiting 'to be executed in the calling thread. Private Declare Function GetInputState Lib "user32" () As Int32
This function is very simple to use. Just simply get its return value to see if any mouse and/or keyboard messages needs processed…
' 'You save ALOT of time by using the GetInputState api call to check 'whether any messages needs to be processed first. The DoEvents() 'method is ONLY fired when there ARE messages that needs to be processed, 'thus really increasing the performance of your application. 'If it returns 0, then there are NO keyboard or mouse messages queued in the thread. If Not GetInputState = 0 Then Application.DoEvents()
In the Example I was talking about earlier I made a simple cpu intensive Loop and benchmarked each of the three scenerio’s.
NO Doevents – 0.011106160…. Seconds.
Doevents WITH GetInputState – 0.397925155…. Seconds.
Doevents ONLY – 8.273245901…. Seconds.
As you can see there are definitely performance/speed differences between each scenario. Of course No DoEvents() will be the highest performing scenerio but at the cost of freezing your application until the code has finished executing. But compare DoEvents() With GetInputState to DoEvents Only. Those are very noticeable differences in performance between the two methods. Simply checking the queue first by using GetInputState() increased performance MANY Times in that test. And as you already know by doing so you will Stop your application from freezing which will allow the user to interact with your application even when your running heavy cpu intensive code.
Anyways that’s all, I hope you got something of use from this tip. Take care… 🙂