Q: Preempt Other Processes
I'm writing an application that must monitor the status of other
applications, somewhat similar to the system Task List utility. My
application needs to be responsive to the user at all times, but I find
that it stalls when another process is performing an intense operation.
How can I crank up my app's response time, even when the system is under
heavy load?
A:
Most processes running on 32-bit versions of Windows are created equal
and receive essentially the same "normal" priority on the
CPU's time as any other. Some processes might need to override the
default priority assigned to them to preempt other processes, or to run
only when other processes are inactive. In your case, you want to assign
a high priority to your process to claim more opportunities for CPU
cycles than the system would allocate otherwise. Use this setting
with extreme caution, as a high-priority process has the capability of
consuming nearly all available CPU time.
The procedure for altering a process's priority is relatively
straightforward. You first call OpenProcess to obtain a handle to the
desired process. You must have PROCESS_SET_INFORMATION access rights to
ensure success. After opening the process, call the SetPriorityClass API
to set the desired priority level. Clean up by calling CloseHandle on
the process handle. Follow the same general procedure to read a
process's priority setting, but call the GetPriorityClass API instead.
If you call the GetPriorityClass API, you need only
PROCESS_QUERY_INFORMATION access rights to the process.
Make these priority adjustments as easy as possible by wrapping them
into a pair of routines that accept either a process ID or a window
handle as a pointer to the desired process (see Listing
1). Most often, determining your process's handle—required to open
the process—involves an extra API call, while you always know the
window handle for your forms. So I coded the call to
GetWindowThreadProcessId directly within my utility routines.
GetWindowThreadProcessId accepts a window handle in its first parameter,
and returns the associated process ID in its second parameter. Call
SetProcessPriority by passing a known window handle and the desired
priority:
Call SetProcessPriority( _
hWnd:=Me.hWnd, Priority:=ppHigh)
You must also be aware that while you're executing within the Visual
Basic IDE, you're a part of VB's process. That is, changing
"your" application's setting actually changes the setting for
VB itself. This might not be desirable. Two approaches you might want to
consider would be to reset the process priority back to
"normal" before your application ends, or to test for your
application's compiled state before adjusting its priority. —K.E.P.
About the Author
Karl E. Peterson is a GIS analyst with a regional transportation
planning agency and serves as a member of the VSM
Editorial Advisory Board. Online, he's a Microsoft MVP and a
section leader on several DevX forums. Find more of Karl's VB
samples at www.mvps.org/vb.
|