TicketToTotalitarianism
asked on
[threads] APC?
according to MDSN.
Asynchronous Procedure Calls
An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread, the system issues a software interrupt. The next time the thread is scheduled, it will run the APC function. APCs made by the system are called "kernel-mode APCs." APCs made by an application are called "user-mode APCs." A thread must be in an alertable state to run a user-mode APC.
When are you making an APC? when a public method of a Tthread-descendant is called from the main thread? (for instance)
Thus if the thread is in a waitstate via SleepEx(1,true), the thread can wake-up when a thread-function is called from the main-thread?
Asynchronous Procedure Calls
An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread, the system issues a software interrupt. The next time the thread is scheduled, it will run the APC function. APCs made by the system are called "kernel-mode APCs." APCs made by an application are called "user-mode APCs." A thread must be in an alertable state to run a user-mode APC.
When are you making an APC? when a public method of a Tthread-descendant is called from the main thread? (for instance)
Thus if the thread is in a waitstate via SleepEx(1,true), the thread can wake-up when a thread-function is called from the main-thread?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
TicketToTotalitarianism:
This old question needs to be finalized -- accept an answer, split points, or get a refund. For information on your options, please click here-> http:/help/closing.jsp#1
EXPERTS:
Post your closing recommendations! No comment means you don't care.
This old question needs to be finalized -- accept an answer, split points, or get a refund. For information on your options, please click here-> http:/help/closing.jsp#1
EXPERTS:
Post your closing recommendations! No comment means you don't care.
ASKER
that's too bad ... I needed an APC, to let the thread sleep, and wake-up when needed..
SleepEx
The SleepEx function suspends the current thread until one of the following occurs:
- An I/O completion callback function is called
- An asynchronous procedure call (APC) is queued to the thread.
- The minimum time-out interval elapses
SleepEx
The SleepEx function suspends the current thread until one of the following occurs:
- An I/O completion callback function is called
- An asynchronous procedure call (APC) is queued to the thread.
- The minimum time-out interval elapses
The correct way to do this is to use a signalled event. In Delphi this is a TEvent object. For each Thread class you create put a TEvent object is a member variable. This way every thread can be wakeable.
TEThread = class(TThread)
private
m_Event: TEvent;
m_Paused: boolean;
public
procedure Sleep(Timeout: DWORD);
procedure WakeUp;
procedure Pause(pause: boolean);
protected
procedure Execute; override;
published
property Paused: boolean read m_Paused;
end;
procedure TEThread.Sleep(Timeout: DWORD);
begin
m_Event.ResetEvent;
m_Event.WaitFor(Timeout);
end;
procedure TEThread.WakeUp;
begin
m_Event.SetEvent;
end;
// BTW. If you want to pause the thread, be wary of using suspend/resume. These functions will stop your thread processing completely whereas you may just want to allow processing to complete but not do any more until unpaused. suspend/resume calls must also be balanced which is tricky if calling them from different threads (inside and out).
procedure TEThread.Pause(pause: boolean);
begin
if m_Paused <> pause then begin
m_Paused := pause;
if not m_Paused then WakeUp; // may as well wake it up.
end;
end;
procedure TEThread.Execute;
begin
try
while not Terminated do begin
Sleep(..sometime..);
if not Terminated and not Paused then begin
.. do stuff ..
end;
end;
except
// don't allow unhandled exceptions or the thread will GPF - bad if running from, say, a service.
end;
end;
TEThread = class(TThread)
private
m_Event: TEvent;
m_Paused: boolean;
public
procedure Sleep(Timeout: DWORD);
procedure WakeUp;
procedure Pause(pause: boolean);
protected
procedure Execute; override;
published
property Paused: boolean read m_Paused;
end;
procedure TEThread.Sleep(Timeout: DWORD);
begin
m_Event.ResetEvent;
m_Event.WaitFor(Timeout);
end;
procedure TEThread.WakeUp;
begin
m_Event.SetEvent;
end;
// BTW. If you want to pause the thread, be wary of using suspend/resume. These functions will stop your thread processing completely whereas you may just want to allow processing to complete but not do any more until unpaused. suspend/resume calls must also be balanced which is tricky if calling them from different threads (inside and out).
procedure TEThread.Pause(pause: boolean);
begin
if m_Paused <> pause then begin
m_Paused := pause;
if not m_Paused then WakeUp; // may as well wake it up.
end;
end;
procedure TEThread.Execute;
begin
try
while not Terminated do begin
Sleep(..sometime..);
if not Terminated and not Paused then begin
.. do stuff ..
end;
end;
except
// don't allow unhandled exceptions or the thread will GPF - bad if running from, say, a service.
end;
end;
ASKER