| 參數 | False | True |
| bManualReset | **自動重置**:喚醒單一線程後自動歸零 (無信號) | **手動重置**:保持有信號直到手動 ResetEvent,喚醒**所有**等待線程 |
| bInitialState | **無信號 (非觸發)**:建立後線程等待會阻塞 | **有信號 (觸發)**:建立後線程等待立即通過 |
核心控制 API
SetEvent(hEvent):設為有信號 → 釋放等待線程 (手動重置釋放所有,自動重置釋放一個)。
ResetEvent(hEvent):設為無信號 → 後續等待線程阻塞。
PulseEvent(hEvent):原子操作:設為有信號 → 釋放等待線程 → 立即設為無信號。相當於「單次脈衝」,僅喚醒當前正在等待的線程。
API 版完整範例:動態啟動/暫停/脈衝控制
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm)
Button1, Button2, Button3, Button4, Button5: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject); // CreateEvent
procedure Button2Click(Sender: TObject); // CreateThread
procedure Button3Click(Sender: TObject); // ResetEvent
procedure Button4Click(Sender: TObject); // SetEvent
procedure Button5Click(Sender: TObject); // PulseEvent
end;
var Form1: TForm1;
implementation {$R *.dfm}
var f: Integer; hEvent: THandle;
function MyThreadFun(p: Pointer): DWORD; stdcall;
var i, y: Integer;
begin
Inc(f); y := 20 * f;
for i := 0 to 200000 do
if WaitForSingleObject(hEvent, INFINITE) = WAIT_OBJECT_0 then
begin
Form1.Canvas.Lock; Form1.Canvas.TextOut(20, y, IntToStr(i)); Form1.Canvas.Unlock;
end;
Result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Repaint; f := 0;
CloseHandle(hEvent);
hEvent := CreateEvent(nil, True, True, nil); // 手動重置 + 初始有信號
end;
procedure TForm1.Button2Click(Sender: TObject);
var ThreadID: DWORD;
begin
CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ResetEvent(hEvent); // 暫停
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
SetEvent(hEvent); // 啟動
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
PulseEvent(hEvent); // 單次脈衝
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Caption := '建立 Event';
Button2.Caption := '建立線程';
Button3.Caption := 'ResetEvent (暫停)';
Button4.Caption := 'SetEvent (啟動)';
Button5.Caption := 'PulseEvent (單次)';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseHandle(hEvent);
end;
end.
TEvent 封裝類版本 (SyncObjs 單元)
uses SyncObjs;
var MyEvent: TEvent;
procedure TForm1.Button1Click(Sender: TObject);
begin
Repaint; f := 0;
if Assigned(MyEvent) then MyEvent.Free;
MyEvent := TEvent.Create(nil, True, True, ''); // 手動重置、初始有信號、無名
end;
procedure TForm1.Button2Click(Sender: TObject);
var ThreadID: DWORD;
begin
CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
MyEvent.ResetEvent;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
MyEvent.SetEvent;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
ShowMessage('TEvent 無 PulseEvent 等效方法'); // 可嘗試 PulseEvent(MyEvent.Handle) 但不保證
end;
function MyThreadFun(p: Pointer): DWORD; stdcall;
var i, y: Integer;
begin
Inc(f); y := 20 * f;
for i := 0 to 200000 do
if MyEvent.WaitFor(INFINITE) = wrSignaled then
begin
Form1.Canvas.Lock; Form1.Canvas.TextOut(20, y, IntToStr(i)); Form1.Canvas.Unlock;
end;
Result := 0;
end;
執行效果展示

DFM 定義
object Form1: TForm1
object Button1: TButton OnClick = Button1Click Caption = '建立 Event'
object Button2: TButton OnClick = Button2Click Caption = '建立線程'
object Button3: TButton OnClick = Button3Click Caption = 'ResetEvent'
object Button4: TButton OnClick = Button4Click Caption = 'SetEvent'
object Button5: TButton OnClick = Button5Click Caption = 'PulseEvent'
end
Event 核心優勢總結
| 特性 | Event | Mutex | Semaphore | CriticalSection |
| 動態啟動/暫停 | ✅ Set/Reset | ❌ | ❌ | ❌ |
| 單次脈衝 | ✅ PulseEvent | ❌ | ❌ | ❌ |
| 喚醒所有/單一 | ✅ 手動/自動重置 | 單一 | 計數控制 | 單一 |
| 跨進程 | ✅ 具名 | ✅ 具名 | ✅ 具名 | ❌ |
| 效能 | 核心物件開銷 | 核心物件 | 核心物件 | **用戶態 極快** |
實務應用模式
- 工作線程池控制:手動重置 Event 作為「暫停/繼續」開關,主線程隨時
SetEvent/ResetEvent。
- 單次任務觸發:自動重置 Event +
PulseEvent 精確喚醒一個空閒線程。
- 階段同步屏障:多線程各自完成階段 1 →
SetEvent 通知主線程 → 主線程 ResetEvent → 釋放進入階段 2。
- 優雅關閉:全域「退出 Event」,主線程
SetEvent,所有工作線程檢測到退出迴圈。
TEvent 缺失補充
TEvent 缺乏 PulseEvent 封裝,需直接呼叫 API PulseEvent(MyEvent.Handle),但官方文檔不保證此用法穩定,建議關鍵路徑直接用 API。
Event 以其「隨時可控、單次脈衝、全喚醒/單喚醒雙模式」成為複雜線程協調編排的首選核心同步物件。
- 上一篇文章: Delphi 多線程程式設計 (14):WaitableTimer 等待定時器 - 核心 API 詳解與基礎同步範例
- 下一篇文章: Delphi 多線程程式設計 (12):Semaphore 信號量 - 多資源並發同步完整指南
Copyright ©
程式碼之家 All Rights Reserved