Function createwaitabletimer (lptimerattributes: psecurityattributes; {Security} bmanualreset: bool; {true: scheduling multiple threads; false: Scheduling only one thread} lptimername: pwidechar {name}): thandle; stdcall; {return handle} function setwaitabletimer (htimer: thandle; {handle} var lpduetime: tlargeinteger; {start time} lperiod: longint; {interval} pfncompletionroutine: tfntimerapcroutine; {pointer to the callback function} lpargtocompletionroutine: pointer; {parameters for the callback function} fresume: bool {wake up system}): bool; stdcall ;{}
The waitabletimer object is complex. Its basic idea is to run the waiting thread at the specified time.
Like other similar objects, createwaitabletimer must be created first. The second parameter of the function is used to determine whether to schedule a thread or all the waiting threads. This is the same as the signal object (semaphore) some are similar, but semaphore can specify the specific number of thread drivers.
Unlike other similar objects, the waitabletimer object does not start working immediately after createwaitabletimer;
Call the setwaitabletimer function to make it work. This is a bit like an event object.
The setwaitabletimer function is troublesome and takes time, for example:
VaR hwaitabletimer: thandle; {the handle variable of the waitabletimer object should be global} procedure handle (Sender: tobject); var duetime: int64; begin {create a waitabletimer object and return a handle} hwaitabletimer: = createwaitabletimer (nil, true, nil); {true in the middle indicates that multiple threads can be driven} duetime: = 0; {This will be the second parameter of setwaitabletimer; because it is a VaR parameter, the constant} setwaitabletimer (hwaitabletimer, {waitabletimer object handle} duetime, {start time, here 0} 0, {interval, here we also give 0} Nil , {No callback function} nil. {of course, no callback function parameter is required.} false {if this value is true, even if the system is in screen saver or standby status, once the time reaches the thread and the system will be awakened !} ); End; {Note: the start time (the second parameter) has three Assignment Methods: 1.> 0 is the absolute time, it is a time in tfiletime format (detailed description is provided later); 2,
In the first example, we will try to use it as simply as possible (but this does not reflect its advantages ):
When createwaitabletimer was created, we decided to allow it to control multiple threads;
When setwaitabletimer is set, let it participate in the control immediately and only execute it once without using the callback function.
In this example:
Code File:
Unit unit1; interfaceuses windows, messages, extensions, variants, classes, graphics, controls, forms, dialogs, stdctrls; Type 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; {handle waiting for the 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 1000 do begin form1.canvas. lock; form1.canvas. textout (20, Y, inttostr (I); form1.canvas. unlock; sleep (1); 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.formdestroy (Sender: tobject); begin closehandle (hwaitabletimer); end.
Form file:
Object form1: tform1 left = 0 Top = 0 caption = 'form1' clientheight = 116 clientwidth = 179 color = clbtnface font. charset = default_charset font. color = clwindowtext font. height =-11 font. name = 'tahoma 'font. style = [] oldcreateorder = false ondestroy = formdestroy pixelsperinch = 96 textheight = 13 object button1: tbutton left = 96 Top = 83 width = 75 Height = 25 caption = 'button1' taborder = 0 onclick = button1click endend
The following is an example of an execution every half second (500 ms) (the same as the form file ):
In this example:
Code file:
Unit unit1; interfaceuses windows, messages, extensions, variants, classes, graphics, controls, forms, dialogs, stdctrls; Type 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. Wait for it to be in the loop.} For I: = 0 to 1000 do begin if waitforsingleobject (hwaitabletimer, infinite) = wait_object_0 then begin form1.canvas. lock; form1.canvas. textout (20, Y, inttostr (I); form1.canvas. unlock; // sleep (1); 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, 500, nil, nil, false ); {500 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.