Delphi多线程编程(15)--多线程同步之WaitableTimer(等待定时器对象)[续]
转载自:万一的博客
本次专门研究下 SetWaitableTimer的第二个参数(起始时间)
它有正值、负值、0值这三种情况,前面已经用过 0 值
先学习负值(相对时间),也就是从当前算起隔多长时间开始执行
这个相对时间是以 1/100 纳秒为单位的,譬如赋值:3*10000000 相当于 3 秒
1 s(秒) = 1,000 ms(毫秒); 1 s(秒) = 1,000,000 µs(微妙); 1 s(秒) = 1,000,000,000 ns(纳秒); 1 s(秒) = 1,000,000,000,000 ps(皮秒);
本例的效果图
代码文件
unit Unit1; interface uses Windows, Messages, SysUtils, 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; 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; end; Result:= 0; end; procedure TForm1.Button1Click(Sender: TObject); var ThreadID: DWORD; DueTime: Int64; begin hWaitableTimer:= CreateWaitableTimer(nil, True, nil); DueTime:= -3*10000000; //3秒钟之后执行 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; end.
窗体文件
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 end end
当我们需要一个绝对时间,譬如 2009-2-18 13:10:5,函数需要的Int64 值应该是 TFileTime格式的时间
先看三种相关时间类型(TFileTime、TSystemTime、TDateTime)的定义
//TFileTime 又名 FILETIME或_FILETIME _FILETIME = record dwLowDateTime: DWORD; dwHighDateTime: DWORD; end; //TSystemTime 又名 SYTEMTIME 或 _SYSTEMTIME _SYSTEMTIME=record wYear: Word; wMonth: Word; wDayOfWeek: Word; wDay: Word; wHour: Word; wMinute: Word; wSecond: Word; wMilliseconds: Word; end; TDateTime= type Double;
TFileTime 相当于一个Int64, 一般要通过 TSystemTime 或TDateTime 赋值,然后转换过去
在例子中,我是通过下面过程转换过去的:
StrToDateTime->DateTimeToSystemTime->SystemTimeToFileTime->LocalFileTimeToFileTime
下面程序执行在2009年2月18号下午1点10分5秒时运行三个线程(窗体同上,我已经找到了合适的时间测试成功)
unit Unit1; interface uses Windows, Messages, SysUtils, 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; 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; end; Result := 0; end; procedure TForm1.Button1Click(Sender: TObject); const strTime = ‘2009-2-18 13:10:5‘; var ThreadID: DWORD; DueTime: Int64; st: TSystemTime; ft,UTC: TFileTime; dt: TDateTime; begin DateTimeToSystemTime(StrToDateTime(strTime), st); {从 TDateTime 到 TSystemTime} SystemTimeToFileTime(st, ft); {从 TSystemTime 到 TFileTime} LocalFileTimeToFileTime(ft, UTC); {从本地时间到国际标准时间 UTC} DueTime := Int64(UTC); {函数需要的是 Int64} hWaitableTimer := CreateWaitableTimer(nil, True, nil); 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; end.
接下来该是WaitableTimer 对象的回调函数了
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。