首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 精確延遲函式:保持訊息迴圈回應的 Sleep 替代方案

     編輯:Delphi

問題背景

Sleep 會阻塞執行緒,導致介面凍結、無法處理訊息 (重繪、按鈕點擊等)。在需要短暫延遲但必須保持 UI 回應的場合,需自訂延遲函式並呼叫 Application.ProcessMessages。

實作程式碼

procedure Delay(MilliSeconds: Integer);
var
  StartTick: DWORD;
begin
  StartTick := GetTickCount;
  repeat
    Application.ProcessMessages;  // 處理排隊訊息,保持 UI 回應
  until (GetTickCount - StartTick) >= Cardinal(MilliSeconds);
end;

使用範例

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := '步驟 1';
  Delay(1000);  // 延遲 1 秒,介面仍可移動、重繪
  Label1.Caption := '步驟 2';
  Delay(500);
  Label1.Caption := '完成';
end;

關鍵點說明

  • GetTickCount 回傳系統啟動至今毫秒數 (DWORD),差值運算自動處理溢位 (無符號減法)。
  • Application.ProcessMessages 會處理所有待處理訊息,包含重繪、滑鼠、鍵盤、定時器等。
  • 警告:重入風險!若延遲期間使用者再次觸發同一事件,可能導致遞迴呼叫。解法:延遲前停用相關控制項 (Button1.Enabled := False) 或使用旗標防重入。
  • 長延遲 (超過數秒) 建議改用 TTimer 或執行緒,避免阻塞主執行緒過久。
  • 高精度需求可用 QueryPerformanceCounter 替代 GetTickCount (約 15ms 解析度)。

進階版本:防重入延遲

procedure SafeDelay(MilliSeconds: Integer; var ReentrancyGuard: Boolean);
begin
  if ReentrancyGuard then Exit;
  ReentrancyGuard := True;
  try
    Delay(MilliSeconds);
  finally
    ReentrancyGuard := False;
  end;
end;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved