利用主线程与子线程间的消息通讯,实现任务处理队列

来源:互联网 发布:初中答题软件 编辑:程序博客网 时间:2024/05/12 00:13

http://hi.baidu.com/dushm/item/14eb022b30a21df950fd873b

From: http://www.delphibbs.com/keylife/iblog_show.asp?xid=27182

主题:利用主线程与子线程间的消息通讯,实现任务处理队列.

目标:主线程只需发命令(消息)通知子线程需要处理的内容,而不用管任务的处理进度,可以发任意个命令,而子线程依次取出主线程交付的任务来处理.

步骤:
     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;


原创粉丝点击