程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 多線程編程(16) - 多線程同步之WaitableTimer(等待定時器對象)[續二](3)

多線程編程(16) - 多線程同步之WaitableTimer(等待定時器對象)[續二](3)

編輯:Delphi

在上面例子中, 每點一次鼠標, 那個回調函數才執行一次; 作為定時器, 如果想讓它每秒執行一次怎麼弄?

但每一次執行那個 APC 函數, 都得有 SleepEx(當然不止它)給送進去, 那這樣得反復調用 SleepEx 才可以.

怎麼調用, 用循環嗎? 別說網上能找到的例子我沒見到不用循環的(太笨了), 就在那個 APC 函數裡調用不就完了.

當然這時一般要設時間間隔的, 下面我們將設間隔為 1000(1秒).

但接著問題又來了, 譬如把代碼修改成:

var
 hTimer: THandle;
procedure TimerAPCProc(lpArgToCompletionRoutine: Pointer; dwTimerLowValue: DWord;
 dwTimerHighValue: DWord); stdcall;
begin
 Form1.Text := IntToStr(StrToIntDef(Form1.Text, 0) + 1);
 SleepEx(INFINITE, True); {這裡再次調用 SleepEx}
end;
procedure TForm1.Button1Click(Sender: TObject);
var
 DueTime: Int64;
begin
 hTimer := CreateWaitableTimer(nil, True, nil);
 DueTime := 0;
 {下面的參數 1000 表示間隔 1秒}
 if SetWaitableTimer(hTimer, DueTime, 1000, @TimerAPCProc, nil, False) then
 begin
  SleepEx(INFINITE, True);
 end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
 CloseHandle(hTimer);
end;

任務能完成, 但窗體"死"了... 怎麼辦? 嘿, 現在學的不是多線程嗎?

下面例子中, 同時使用了 CancelWaitableTimer 來取消定時器, 很好理解;效果圖:

代碼文件:

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls;
type
 TForm1 = class(TForm)
  Button1: TButton;
  Button2: TButton;
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
var
 hTimer: THandle;
{APC 函數}
procedure TimerAPCProc(lpArgToCompletionRoutine: Pointer; dwTimerLowValue: DWord;
 dwTimerHighValue: DWord); stdcall;
begin
 Form1.Text := IntToStr(StrToIntDef(Form1.Text, 0) + 1);
 SleepEx(INFINITE, True);
end;
{線程入口函數}
function MyThreadFun(p: Pointer): Integer; stdcall;
var
 DueTime: Int64;
begin
 DueTime := 0;
 {SetWaitableTimer 必須與 SleepEx 在同一線程}
 if SetWaitableTimer(hTimer, DueTime, 1000, @TimerAPCProc, nil, False) then
 begin
  SleepEx(INFINITE, True);
 end;
 Result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
 ID: DWord;
begin
 {建立 WaitableTimer 對象}
 if hTimer = 0 then hTimer := CreateWaitableTimer(nil, True, nil);
 CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); {建立線程}
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
 CancelWaitableTimer(hTimer); {取消定時器}
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
 CloseHandle(hTimer);
end;
end.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved