This program shows how to use true threads in Clarion and specifically how to use an Event that a Thread should wait on.
Note: Beginning with Clarion 6, True Background Threads can be created using the Clarion Start procedure. See the Notes section at the end of this document for Clarion 6 specific information.
A thread in this discussion is a Background Procedure that is started with the Windows API and not the Clarion Start() procedure.
Running a background Thread in Clarion is easy just so long as you don't use any Clarion Functions that rely upon an Accept Loop. This means you actually can Start a Background Thread that does this:
Loop
End
and your Clarion program will continue to run. If you try to Start() the same procedure using Clarion, your program will come to a halt (Clarion versions prior to 6). This is because Clarion threads use cooperative multi-tasking which depends upon an Accept Loop to operate properly.
When using true threads, you can not use any Clarion function that needs an Accept Loop (this rules out all Window Related Procedures and Functions). If your Thread has something to display, then Post a Message to some other Clarion Procedure and let it display the message.
In this Example, we are doing two things:
The Thread is the Procedure that does the waiting for the Event.
The Event that the Thread is "waiting for" is a change in the current directory. Whenever a file in the current directory has been modified, the Thread will "wake up" and Post a Message to the Main Window to tell the Main Thread to update its Status Bar.
The Main Thread is actually the one that is updating the File that the Background Thread is "waiting on"!
The Thread that is running uses no Processor ticks and is not taking up any of the Program's time slice. It runs in the background until Windows wakes it up (it uses no clock ticks and doesn't generate any Messages to the message queue).
With a Timer Event, the Event will fire off on the Interval you set. In this case, the Timer Event will have to check the Directory to see if anything has changed. Why check if nothing has changed?
Timer Events are a work-around. They are not a solution. Especially for a disk intensive Thread such as this example. Windows has the solutions, its just a matter of using them correctly in our Clarion Programs.
- A change to the directory occurs, or
- The second event, EventHandles[2], is signaled by the main procedure when the program shuts down.
Upon "waking up", the thread first checks if the application is closing (either the variable AppClosing is true and/or the return value from WaitForMultipleObjects is set to 1 (meaning the second event caused it to return). If the App is closing, the thread returns and the program will no longer be notified of Directory Changes.
If the App is not closing, the thread posts an Event to the main procedure to tell it to update its Status Bar. The thread then resets the change notification event and goes to the top of the loop to repeat the process.
Clarion 6 implements true, preemptive, multi-tasking threads. These are the same types of threads we would create using the Windows API. In the Clarion 6 wait.app program, we use the Clarion Start() procedure instead of the CreateThread API. This is the only difference between the Version 5 and Version 6 applications. Clarion 6 finally alleviates the need for Timer Events to wait for something to occur.
Kenny Gardner
GAP Development Company
http://www.gapdev.com/
February 9, 1999
Updated, September 27, 2004