主题:利用主线程与子线程间的消息通讯,实现任务处理队列. 目标:主线程只需发命令(消息)通知子线程需要处理的内容,而不用管任务的处 理进度,可以发任意个命令,而子线程依次取出主线程交付的任务来处理. 步骤: 1.主线程通过 PostThreadMessage 将命令消息发送给子线程,可以利用 wParam 与 lParam 传递需要的参数. 2.子线程执行代码中建立一个消息循环,PeekMessage 从消息队列提取消息, 若无消息,则用 MsgWaitForMultipleObjects 等待消息或事件对象. 示例代码: const WM_TEST=WM_USER+1; var hCloseEvent:THandle; ThreadID:DWORD; type TTestThread=class(TThread) protected procedure Execute;override; end; procedure TTestThread.Execute; var msg:TMsg; begin try while True do begin if not PeekMessage(msg,0,0,0,PM_REMOVE) then begin case MsgWaitForMultipleObjects(1,hCloseEvent,False,INFINITE,QS_ALLINPUT) of WAIT_OBJECT_0: Break;//hCloseEvent 事件已经有效,故结束 WAIT_OBJECT_0+1:Continue;//消息队列中有消息存在 else Break;//其它情况,WM_FAILED 或 WAIT_ABANDONED_0,表明已经 出错,故结束 end;
end else begin if WaitForSingleObject(hCloseEvent,0)<>WAIT_TIMEOUT then Break; case msg.message of WM_TEST: begin //...接到主线程发过来的命令,作相应处理 //...处理完之后,也可以用消息通知主线程 end; end; end; end; finally //...作善后处理 end; end; procedure TForm1.btnCmdClick(Sender: TObject); begin //给子线程发送消息 PostThreadMessage(ThreadID,WM_TEST,0,0); end; procedure TForm1.FormCreate(Sender: TObject); begin //建立事件对象以及子线程,并保存子线程的 ThreadID,用以调用 PostThreadMessage hCloseEvent:=CreateEvent(nil,True,False,0); ThreadID:=TTestThread.Create(False).ThreadID; end; procedure TForm1.FormDestroy(Sender: TObject); begin SetEvent(hCloseEvent); CloseHandle(hCloseEvent); end; procedure TForm1.btnStopClick(Sender: TObject); begin SetEvent(hCloseEvent); end;