Reprinted from: In Case of blog
function CreateWaitableTimer ( lptimerattributes:psecurityattributes; Safety Bmanualreset:bool; True: Multiple threads can be dispatched; False: only one thread Lptimername:pwidechar //Name is dispatched): Thandle; stdcall; Returns the handle function SetWaitableTimer ( htime:thandle; Handle var Lpduetime:tlargeinteger; Starting time Lperiod:longint; Interval time pfncompletionroutine:tfntimerapcroutine; Pointer to the callback function Lpargtocompletionroutine:pointer; Give the parameter of the callback function Fresume:bool; Whether the system is awakened): BOOL; stdcall;
The Waitabletimer object is complex, and the basic idea is to have the waiting thread run at a specified time
Like other similar objects, to establish first (CreateWaitableTimer), the second parameter of the establishment function determines whether to dispatch a thread or all waiting threads, which is somewhat similar to the Signal object (Semaphore). However, Semaphore can specify the number of threads that can be driven
Unlike other similar objects: After CreateWaitableTimer, the Waitabletimer object did not start working immediately
The SetWaitableTimer function is then dispatched to make it work, which is a bit like an event object
The SetWaitableTimer function is more troublesome, so take it slow, for example, using
var hwaitabletimer:thandle; The handle variable of the Waitabletimer object should be global procedure Tform1.button1click (sender:tobject); var duetime:int64;begin {Build Waitabletimer the object and returns the handle} hwaitabletimer:= CreateWaitableTimer (nil. True, nil); The middle of TRUE indicates that multiple threads can be driven duetime:= 0; This will be the second parameter of SetWaitableTimer, because it is a var parameter and cannot be directly given to the constant SetWaitableTimer (Hwaitabletimer, the handle of the//waitabletimer object duetime, //Start time, here is 0 0, //Interval time, here is also 0 nil, //temporarily without the callback function nil, // Of course, there is no need for the callback function parameter False //This value if true, even if the system is in a screensaver or standby state, the time of the thread and the system will be awakened ); end;
Note again:
The Starting time (the second parameter) has three methods of assignment:
1) >0 is the absolute time, is a tfiletime format time (detailed after the specific assignment method)
2) <0 is relative time, relative to current, for example-50000000 means 5 seconds after execution (unit is 0.1 milliseconds, detailed later)
3) = 0 o'clock, execute immediately, do not wait; The above example and the first example below we first use 0
The interval time (the third parameter) has two conditions:
1) For example, 5000 means that every 5 seconds, the unit is milliseconds; This page The second example uses 500 (half a second)
2) If the assignment is 0, it is executed only once, based on the start time, and is no longer repeated
The callback function and its arguments (the fourth to fifth parameter), which involves a more complex topic (APC), is not used temporarily, and later
The last parameter is the last parameter is already clear, I also tested (respectively in the screensaver and standby), very effective!
In the first example we will try to use it as simply as possible (but this does not show its advantages):
CreateWaitableTimer, we decided to let it control multiple threads.
SetWaitableTimer let it participate in control immediately, execute only once, and do not use a callback function
This example
Code files
Unit unit1;interfaceuses Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms, Dialogs, Stdctrls;ty PE TForm1 = Class (Tform) Button1:tbutton; Procedure Button1Click (Sender:tobject); Procedure Formdestroy (Sender:tobject); End;var form1:tform1;implementation{$R *.dfm}var F:integer; Hwaitabletimer:thandle; The handle of the waiting Timer object function Mythreadfun (p:pointer); DWORD; Stdcall;var I, Y:integer;begin Inc (f); Y:= 20*f; If WaitForSingleObject (Hwaitabletimer, INFINITE) =wait_object_0 then begin for i:=0-to-do begin Form1.can Vas. Lock; Form1.Canvas.TextOut (x, Y, IntToStr (i)); Form1.Canvas.UnLock; Sleep (1); End End result:= 0;end;procedure Tform1.button1click (sender:tobject); var Threadid:dword; Duetime:int64;begin hwaitabletimer:= CreateWaitableTimer (nil, True, nil); duetime:= 0; SetWaitableTimer (Hwaitabletimer, duetime, 0, Nil, nil, False); Repaint; f:=0; CreateThread (nil, 0, @MyThreadFun, nil, 0, ThreadID); CreateThread (nil, 0, @MyThreadFun, nil, 0, ThreadID); CreateThread (nil, 0, @MyThreadFun, nil, 0, ThreadID); End;procedure tform1.formdestory (sender:tobject); begin CloseHandle (Hwaitabletimer); For kernel object handles, be sure to turn off end;end.
Form files
Object Form1:tform1 Left = 0 Top = 0 Caption = ' Form1 ' clientheight = $ clientwidth = 179 Color = Clbtnface font.charset = default_charset font.color = clwindowtext font.height = -11 font.name = ' Tahoma ' font.style = [] oldcreateorder = False OnDestroy = Formdestroy pixelsperinch = TextHeight = Object Button1:tbutton left =-----------Width =---------- Caption = ' Button1 ' taborder = 0 OnClick = Button1Click endend
The following is an example of an execution once every half-second (5000ms) (form file Ibid):
This example
Code files
Unit unit1;interfaceuses Windows, Messages, sysutils, variants, Classes, Graphics, Controls, Forms, Dialogs, Stdctrls;ty PE TForm1 = Class (Tform) Button1:tbutton; Procedure Button1Click (Sender:tobject); Procedure Formdestroy (Sender:tobject); End;var form1:tform1;implementation{$R *.dfm}var F:integer; Hwaitabletimer:thandle;function Mythreadfun (p:pointer): DWORD; Stdcall;var I, Y:integer;begin Inc (f); Y:= 20*f; {This is different from the above, put the wait agricultural credit loop inside} for i:= 0 to $ do begin if WaitForSingleObject (Hwaitabletimer, INFINITE) = Wait_object_0 Then Begin Form1.Canvas.Lock; Form1.Canvas.TextOut (x, Y, IntToStr (i)); form1.canvas.unlock;//Sleep (1); End End Result: = 0;end;procedure Tform1.button1click (sender:tobject); var Threadid:dword; Duetime:int64;begin Hwaitabletimer: = CreateWaitableTimer (nil, False, nil); {The parameters here are not the same as above} Duetime: = 0; SetWaitableTimer (Hwaitabletimer, Duetime, N, Nil, nil, False); {MS} Repaint; F: = 0; CreatethreAD (nil, 0, @MyThreadFun, nil, 0, ThreadID); CreateThread (nil, 0, @MyThreadFun, nil, 0, ThreadID); CreateThread (nil, 0, @MyThreadFun, nil, 0, ThreadID); End;procedure Tform1.formdestroy (sender:tobject); begin CloseHandle (Hwaitabletimer); end;end.
Delphi multithreaded Programming (14)--Multithreading synchronization Waitabletimer (Waiting Timer object)