Mas*_*ler 3 windows delphi service winapi
我正在使用一个主循环看起来像这样的服务:
while (fServer.ServerState = ssStarted) and (Self.Terminated = false) do
begin
Self.ServiceThread.ProcessRequests(false);
ProcessFiles;
Sleep(3000);
end;
Run Code Online (Sandbox Code Playgroud)
ProcessRequests很像Application.ProcessMessages.我无法传递true给它,因为如果我这样做,它会阻塞,直到从Windows收到消息,并且ProcessFiles将无法运行,并且它必须不断运行.Sleep可以降低CPU使用率.
这工作正常,直到我尝试从Windows的服务管理列表关闭服务.当我点击Stop时,它会发送一条消息并希望几乎立即得到响应,如果它在Sleep命令的中间,Windows会给我一个错误,表明该服务没有响应Stop命令.
所以我需要说的是"睡觉3000或直到你收到消息,以先到者为准".我确定有一个API,但我不确定它是什么.有人知道吗?
Jer*_*ers 11
这种东西很难做到,所以我通常从MSDN的API文档开始.
该WaitForSingleObject的机制的文档特别指示,以MsgWaitForMultipleObjects这些种情况:
调用等待函数和直接或间接创建窗口的代码时要小心.如果一个线程创建了任何窗口,它必须处理消息.消息广播被发送到系统中的所有窗口.使用没有超时间隔的等待函数的线程可能会导致系统死锁.间接创建窗口的两个代码示例是DDE和 CoInitialize函数.因此,如果您有一个创建窗口的线程,请使用MsgWaitForMultipleObjects 或MsgWaitForMultipleObjectsEx,而不是
WaitForSingleObject.
在MsgWaitForMultipleObjects中,您有一个dwWakeMask参数指定要返回的排队消息,以及一个描述您可以使用的掩码的表.
由于Warren P的评论而编辑:
如果您的主循环可以通过ReadFileEx,WriteFileEx或QueueUserAPC继续,那么您可以使用SleepEx.
--jeroen
MsgWaitForMultipleObjects() is the way to go, ie:
while (fServer.ServerState = ssStarted) and (not Self.Terminated) do
begin
ProcessFiles;
if MsgWaitForMultipleObjects(0, nil, FALSE, 3000, QS_ALLINPUT) = WAIT_OBJECT_0 then
Self.ServiceThread.ProcessRequests(false);
end;
Run Code Online (Sandbox Code Playgroud)
If you want to call ProcessFiles() at 3 second intervals regardless of any messages arriving, then you can use a waitable timer for that, ie:
var
iDue: TLargeInteger;
hTimer: array[0..0] of THandle;
begin
iDue := -30000000; // 3 second relative interval, specified in nanoseconds
hTimer[0] := CreateWaitableTimer(nil, False, nil);
SetWaitableTimer(hTimer[0], iDue, 0, nil, nil, False);
while (fServer.ServerState = ssStarted) and (not Self.Terminated) do
begin
// using a timeout interval so the loop conditions can still be checked periodically
case MsgWaitForMultipleObjects(1, hTimer, False, 1000, QS_ALLINPUT) of
WAIT_OBJECT_0:
begin
ProcessFiles;
SetWaitableTimer(hTimer[0], iDue, 0, nil, nil, False);
end;
WAIT_OBJECT_0+1: Self.ServiceThread.ProcessRequests(false);
end;
end;
CancelWaitableTimer(hTimer[0]);
CloseHandle(hTimer[0]);
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1024 次 |
| 最近记录: |