转载自:https://www.cnblogs.com/lackey/p/6337357.html
unit uJooThread;
interface
uses
Classes, uFooThread;
type
TJooThread = class(TFooThread)
public
procedure Synchronize(AProc: TThreadMethod);
end;
implementation
{ TJooThread }
procedure TJooThread.Synchronize(AProc: TThreadMethod);
begin
ExecProcInThread(AProc);
// 再设计一个等待 AProc 执行结果功能。
end;
end.
unit uJooThread;
interface
uses
Classes, SyncObjs, uFooThread, uFooList;
type
PSyncRec = ^TSyncRec;
TSyncRec = record
Method: TThreadMethod; // 这是类的方法
Proc: TThreadProcedure; // 这是匿名方法
// 本例只写了类的方法。需要匿名方法,请自行重载 Sync 与 Queue
Signle: TEvent;
Queue: boolean;
end;
TSyncRecList = class(TFooList<PSyncRec>) //用于装执行代码的 List
protected
procedure FreeItem(Item: PSyncRec); override;
end;
TJooThread = class(TFooThread)
private
FSyncRecList: TSyncRecList;
procedure Check;
public
constructor Create(ACanAccessCom: boolean);
destructor Destroy; override;
procedure Synchronize(AProc: TThreadMethod); // 阻塞到 AProc执行完毕才返回。
procedure Queue(AProc: TThreadMethod); // 塞入线程后立即返回。
end;
// 本例就是前面单节讲的知识的综合运用。
// TEvent,FooThread,FooList,全都用上了。
// 并构建了一个新的线程功能。
// 当我写完以后发现,与系统源码中,
// 窗口接收 WM_NULL 消息后的处理UI操作的功能,几乎是一模一样的。
// 不同的是,本例是在线程时空,系统源码是在主线程时空。
implementation
{ TJooThread }
procedure TJooThread.Check;
var
p: PSyncRec;
begin
FSyncRecList.Lock; // 所有要执行的代码,都在这个 List 中了。
// 此处是线程时空,故从List 中取出并执行代码即可。
try
p := nil;
if FSyncRecList.Count > 0 then // 每次取 List 的第一个来执行。
begin
p := FSyncRecList[0];
FSyncRecList.Delete(0);
end;
finally
FSyncRecList.Unlock;
end;
if Assigned(p) then
begin
if Assigned(p.Method) then
p.Method
else if Assigned(p.Proc) then
p.Proc();
if not p.Queue then // 如果是阻塞,就置信号。
p.Signle.SetEvent;
Dispose(p);
ExecProcInThread(Check);
end;
end;
constructor TJooThread.Create(ACanAccessCom: boolean);
begin
inherited;
FSyncRecList := TSyncRecList.Create;
end;
destructor TJooThread.Destroy;
begin
FSyncRecList.Free;
inherited;
end;
procedure TJooThread.Queue(AProc: TThreadMethod);
var
p: PSyncRec;
begin
FSyncRecList.Lock;
try
new(p);
FSyncRecList.Add(p);
p.Method := AProc;
p.Queue := true;
ExecProcInThread(Check);
finally
FSyncRecList.Unlock;
end;
end;
procedure TJooThread.Synchronize(AProc: TThreadMethod);
var
p: PSyncRec;
o: TEvent;
begin
FSyncRecList.Lock;
try
new(p);
FSyncRecList.Add(p);
p.Method := AProc;
o := TEvent.Create(nil, true, false, ‘‘);
p.Signle := o;
p.Queue := false;
ExecProcInThread(Check); //触发线程启动
finally
FSyncRecList.Unlock;
end;
o.WaitFor; // 等待 AProc 执行完毕的信号
o.Free;
end;
{ TSyncRecList }
procedure TSyncRecList.FreeItem(Item: PSyncRec);
begin
inherited;
if Assigned(Item.Signle) then
Item.Signle.Free;
Dispose(Item);
end;
end.
delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行
原文:https://www.cnblogs.com/approx/p/11852351.html