WaitForMultipleObject与MsgWaitForMultipleObjects用法 .
CSDN上的同步小Demo:
主线程:
unit Unit1;
interface
uses
LongWaitTrd,
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btnSetTask: TButton;
btnExitThd: TButton;
btnCreateTrd: TButton;
Edit1: TEdit;
Label1: TLabel;
Button2: TButton;
Button1: TButton;
Edit2: TEdit;
Label2: TLabel;
procedure btnSetTaskClick(Sender: TObject);
procedure btnCreateTrdClick(Sender: TObject);
procedure btnExitThdClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
LongWaitThread:TLongWaitTrd;
FCreationTime{线程创建时间},FExitTime{线程退出时间},
FKernelTime{操作系统代码时间},FUserTime{应用程序本身代码时间}:TFileTime;
procedure OnThreadMessage(var Message: TMessage); message WM_USER+2000;
procedure OnTerminate(Sender:TObject);
function FileTimeToDateTime(FileTime:TFileTime):TDateTime;
Function DateTimeToFileTime(DateTime:TDateTime):TFileTime;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnSetTaskClick(Sender: TObject);
begin
//将一个消息放入(寄送)到指定线程的消息队列里,不等待线程处理消息就返回
if (LongWaitThread<>nil) then PostThreadMessage(LongWaitThread.ThreadID,WM_USER+1000,0,0);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if LongWaitThread<>nil then
LongWaitThread.Priority:= tpHighest;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if LongWaitThread<>nil then
case LongWaitThread.Priority of
tpIdle:edit2.Text:='tpIdle';
tpLowest:edit2.Text:='tpLowest';
tpLower:edit2.Text:='tpLower';
tpNormal:edit2.Text:='tpNormal';
tpHigher:edit2.Text:='tpHigher';
tpHighest:edit2.Text:='tpHighest';
tpTimeCritical:edit2.Text:='tpTimeCritical';
end;
end;
function TForm1.DateTimeToFileTime(DateTime: TDateTime): TFileTime;
var SysTime:TSystemTime;
begin
with SysTime do
begin
DecodeDate(DateTime,wYear,wMonth,wDay);
DecodeTime(DateTime,wHour,wMinute,wSecond,wMilliseconds);
wDayofWeek:=DayOfWeek(DateTime);
end;
if not SystemTimeToFileTime(SysTime,Result) then
raise EConvertError.CreateFmt('SystemTimeToFileTime failed.'
+'Error Code %d',[GetLastError]);
end;
function TForm1.FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var SysTime:TSystemTime;
begin
if not FileTimeToSystemTime(FileTime,SysTime) then
raise EConvertError.CreateFmt('FileTimeToSystemTime failed.'
+'Error Code %d',[GetLastError]);
with SysTime do
Result := EncodeDate(wYear,wMonth,wDay)+
EncodeTime(wHour,wMinute,wSecond,wMilliseconds);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if LongWaitThread<>nil then
btnExitThd.OnClick(nil);
end;
procedure TForm1.btnCreateTrdClick(Sender: TObject);
begin
if (LongWaitThread=nil) then
begin
LongWaitThread:=TLongWaitTrd.Create(True); //建立线程,不要立即执行
LongWaitThread.MainWin:=Handle; //将本身句柄传给线程
LongWaitThread.Resume; //开始执行
showmessage('建立线程完成!');
end else
showmessage('线程已成存!');
LongWaitThread.OnTerminate:=OnTerminate;
end;
procedure TForm1.OnTerminate(Sender: TObject);
begin
if LongWaitThread<>nil then
if GetThreadTimes(LongWaitThread.Handle,
FCreationTime{线程创建时间},
FExitTime{线程退出时间},
FKernelTime{操作系统代码时间},
FUserTime{应用程序本身代码时间})
then ;
end;
procedure TForm1.OnThreadMessage(var Message: TMessage);
begin
if Message.Msg= WM_USER+2000 then
begin
Showmessage(String(message.LParam));
end;
end;
procedure TForm1.btnExitThdClick(Sender: TObject);
begin
while True do
Begin
if LongWaitThread<>nil then
begin
if LongWaitThread.ExitLongWaitTrd() then
begin
LongWaitThread:=nil;
Showmessage('LongWaitThread Over!');
break;
end;
end
else
begin
Showmessage('LongWaitThread不存在!');
Break;
end;
end;
end;
end.
子线程:
unit LongWaitTrd;
interface
uses
Classes,Windows,Messages,SyncObjs,SysUtils,Forms;
type
TLongWaitTrd = class(TThread)
private
FMainWin:THandle;
QuitEvent: TEvent;
procedure SendFeedBackToMainWin();
procedure DoTheHardWork();
protected
procedure Execute; override; //通过消息执行任务
public
constructor Create(CreateSuspended: Boolean);
Destructor Destroy; override;
function ExitLongWaitTrd():Boolean;
published
property MainWin:THandle read FMainWin write FMainWin;
end;
implementation
uses Unit1;
constructor TLongWaitTrd.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
end;
destructor TLongWaitTrd.Destroy;
begin
inherited;
end;
procedure TLongWaitTrd.DoTheHardWork();
begin
//form1.Canvas.TextOut(10,10,FormatDateTime('hh:mm:ss',now));
form1.Edit1.Text:=FormatDateTime('hh:mm:ss',now);
end;
procedure TLongWaitTrd.Execute;
var Msg: TMsg;
begin
FreeOnTerminate:=True;
//1.长等待型线程示例
while GetMessage(Msg, 0, 0, 0) do
begin
if (Msg.message=WM_USER+1000) then //任务来了
begin
DoTheHardWork();
SendFeedBackToMainWin;
end;
if (Msg.message=WM_QUIT) then
begin
QuitEvent.SetEvent;
Break;
end;
end;
// }
//2.长工作型线程示例
while(True) do
begin
if Application.Terminated then break;
//该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
if (Msg.message=WM_QUIT) then
begin
QuitEvent.SetEvent;
Break;
end;
end;
DoTheHardWork();
end;
end;
function TLongWaitTrd.ExitLongWaitTrd;
begin
Result:=true;
QuitEvent:=TEvent.Create(nil,True,False,'QuitEvent');
PostThreadMessage(ThreadID,WM_QUIT,0,0);
if (QuitEvent.WaitFor(2000)=wrTimeOut) then
Result:=false;
QuitEvent.Free ;
end;
procedure TLongWaitTrd.SendFeedBackToMainWin();
var Status:String;
begin
if (MainWin<>0) then
begin
Status:='The data has been processed by thread.';
PostMessage(MainWin,WM_USER+2000,0,Integer(Status))
end;
end;
end.