我正在处理一些特定的TForm事件CMControlListChanging,,需要修改该(插入)控件,但是当我尝试这样做时,事情会变得很糟糕,因为显然它并不打算在VCL操作的中间中这样做。
因此,我需要将控制修改的CMControlListChanging延迟到,通过queuing将代码从处理程序中移开,以便在稍后的时间调用。
当然,我可以做PostMessage的事情,但是我想要更通用的方法。
System.Classes单元
类过程同步(ASyncRec: PSynchronizeRecord;QueueEvent: Boolean = False);重载;
它可以完成这个任务,但是它会检查CurrentThread.ThreadID = MainThreadID,如果是,则调用方法我会立即排队。
延迟调用的好方法,至少在主线程上是这样的吗?
发布于 2016-08-17 13:47:49
不确定这是否是您想要的,但是如果您使用的是最近的Delphi版本,这些延迟方法可能会派上用场。在应用了可选的非阻塞延迟后,它们在主线程中执行AProc。
uses
System.Threading,
System.Classes;
procedure Postpone(AProc: TThreadProcedure; ADelayMS: Cardinal = 0); overload;
begin
TTask.Run(
procedure
begin
if ADelayMS > 0 then begin
TThread.Sleep(ADelayMS);
end;
TThread.Queue(nil, AProc);
end);
end;
procedure Postpone(AProc: TThreadMethod; ADelayMS: Cardinal = 0); overload;
begin
TTask.Run(
procedure
begin
if ADelayMS > 0 then begin
TThread.Sleep(ADelayMS);
end;
TThread.Queue(nil, AProc);
end);
end;发布于 2018-09-13 09:10:59
这个怎么样?它不创建新任务,只创建一个新的HWND (接收消息):
TYPE TDelayedProc = REFERENCE TO PROCEDURE;
TYPE
TPostponeClass = CLASS(TWinControl)
CONSTRUCTOR Create(P : TDelayedProc);
STRICT PRIVATE
Proc : TDelayedProc;
PROCEDURE Run(VAR M : TMessage); MESSAGE WM_USER;
END;
CONSTRUCTOR TPostponeClass.Create(P : TDelayedProc);
BEGIN
INHERITED Create(NIL);
Parent:=Application.MainForm;
Proc:=P;
PostMessage(Handle,WM_USER,0,0)
END;
PROCEDURE TPostponeClass.Run(VAR M : TMessage);
BEGIN
Proc;
Free
END;
PROCEDURE Postpone(Proc : TDelayedProc);
BEGIN
TPostponeClass.Create(Proc)
END;它甚至适用于匿名方法,因此您可以推迟执行事件的一部分,并且仍然可以访问局部变量(以及实例"Self")。
像这样使用它:
PROCEDURE WriteFile(CONST F : TFileName ; CONST STR : STRING);
VAR
TXT : TextFile;
BEGIN
AssignFile(TXT,F);
IF FileExists(F) THEN APPEND(TXT) ELSE REWRITE(TXT);
WRITELN(TXT,STR);
CloseFile(TXT)
END;
PROCEDURE TForm37.Button1Click(Sender: TObject);
CONST
N = 'LOGFILE.TXT';
VAR
LocalVar : INTEGER;
BEGIN
DeleteFile(N);
LocalVar:=20;
Postpone(PROCEDURE
BEGIN
WriteFile(N,'Postponed Code: '+Name+' ('+IntToStr(LocalVar)+')')
END);
WriteFile(N,'Last statement in event: '+Name)
END;LOGFILE.TXT文件将包含以下两行:
Last statement in event: Form37
Postponed Code: Form37 (20)为了说明延迟的事件只在事件结束时运行,以及对局部变量的访问。
注意:在延迟调用和事件退出之间运行Application.ProcessMessages吗?如果运行,延迟的代码将在此时运行。
发布于 2018-09-13 10:24:44
从Delphi10.2东京开始,就可以使用TThread方法异步地推迟主线程的调用。
请参阅TThread.ForceQueue
类过程ForceQueue(const AThread: TThread;const AMethod: TThreadMethod);重载;静态;类过程ForceQueue(const AThread: TThread;const AThreadProc: TThreadProcedure);重载;静态; 在主线程中对方法调用的执行进行队列。 与队列不同,AMethod指定的方法调用的执行被强制排队,尽管它是由主线程调用的。 AMethod将调用线程关联起来:
https://stackoverflow.com/questions/38997386
复制相似问题