Hi,
I'm writing a program in LabWindows/CVI that continuously reads data from the comport, refreshing the GUI with the new information. My first attempt to do this was like so:
while (!done) {
RefreshFromComPort (); // my function
ProcessSystemEvents (); // Standard CVI function
}
This worked OK except that every time the user activated a button or pulled down a menu, ProccessSystemEvents wouldn't return until it was released, so the panels would not refresh during that time.
I've found two ways to get something to happen during this time: run it in a callback or run it in a separate thread. However, my attempts at using either of these methods resulted in performance that was less than ideal.
When using the callback method, I had the RefreshFromComPort function called by a Timer with an interval of 0. This allowed the panels to refresh at a reasonable rate, and continue to do so when they would normally have been blocked. However, interaction with controls in this version was quite sluggish, especially noticeable with text boxes. Anyone know how to improve this? (Note to CVI devel team: I don't know how 0 delay timers are currently implemented, but the functionality that I feel would be most useful is to push a EVENT_TIMER_TICK onto the event queue when the program is first started and then every time the event is processed (it's callback called) after that. That way these events would be created as fast as they can be handled, but still allow other events to get into the event queue ASAP).
The third method I attempted was running the RefreshFromComPort function (in a loop) in its own thread, and calling RunUserInterface in main. In my original code, the RefreshFromComPort was using about 2/3 of the CPU time and the ProcessSystemEvents the other 1/3. I expected that by running the comport code in a separate thread I should be able to get better performance since the RunUserInterface code could be run while the comport thread is waiting for data. However, to my surprise, when I rewrote the program to use separate threads, the I actually got much worse performance. I don't know why this is so, but have a few ideas. I noticed that in this version, I could see each control refreshing individually (I update 1 panel with up to 100 numeric controls for each call to RefreshFromComPort), whereas in the other 2 versions, LabWindows didn't have a chance to handle any redraw events until I had changed all the controls I wanted to change on a panel. Could this be what is causing RunUserInterface to use more time that it used to? Is there a way for me to (partially) freeze the panel, to let me do the updates I want, and then unfreeze it when I'm ready for it to redraw the panel in light of the changes? (while preferably still allowing the user to interact with the panel 😉 Any other ideas on why this is slower?
I figured that since my program is a textbook example of what LabWindows/CVI was designed for, there is probably a fairly simple way to do what I want, and I am simply missing it. I will greatly appreciate any suggestions for fixing one of the three methods I presented above or a different way of approaching the problem that will work better.
Thank you.
D. Jackson Peacock
PS. I'm using LabWindows/CVI 5.5 in Windows 2000