展示在 IdTCPServer.OnConnect 等工作線程中直接操作 UI 導致死鎖,以及正確使用 CreateThread / Synchronize 保持界面響應的對比。
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;
type
TForm1 = class(TForm)
UsedThread: TBitBtn;
NoUsedThread: TBitBtn;
procedure UsedThreadClick(Sender: TObject);
procedure NoUsedThreadClick(Sender: TObject);
end;
var Form1: TForm1;
implementation {$R *.dfm}
function MyThreadFunc(P: Pointer): Longint; stdcall;
var i: Longint; DC: HDC; S: string;
begin
DC := GetDC(Form1.Handle);
for i := 0 to 500000 do begin
S := IntToStr(i);
TextOut(DC, 10, 10, PChar(S), Length(S));
end;
ReleaseDC(Form1.Handle, DC);
Result := 0;
end;
procedure TForm1.UsedThreadClick(Sender: TObject);
var hThread: THandle; ThreadID: DWORD;
begin
hThread := CreateThread(nil, 0, @MyThreadFunc, nil, 0, ThreadID);
if hThread = 0 then MessageBox(Handle, 'Didn''t Create a Thread', nil, MB_OK);
end;
procedure TForm1.NoUsedThreadClick(Sender: TObject);
begin
MyThreadFunc(nil); {主線程直接執行,UI 完全凍結直到循環結束}
end;
end.
推薦使用 TThread 類或 TTask.Run (PPL) 替代底層 CreateThread,自動處理異常、同步、線程池復用。