【更新说明】
1、TQJob.Synchronize 新增匿名函数版本;
2、新增 RunInMainThread 系列函数:
TMainThreadProc=procedure (AData:Pointer) of object; TMainThreadProcG=procedure (AData:Pointer); /// <summary>在主线程中执行指定的函数</summary> /// <param name="AProc">要执行的函数</param> /// <param name="AData">附加参数</param> procedure RunInMainThread(AProc:TMainThreadProc;AData:Pointer);overload; /// <summary>在主线程中执行指定的函数</summary> /// <param name="AProc">要执行的函数</param> /// <param name="AData">附加参数</param> procedure RunInMainThread(AProc:TMainThreadProcG;AData:Pointer);overload; /// <summary>在主线程中执行指定的函数</summary> /// <param name="AProc">要执行的函数</param> procedure RunInMainThread(AProc:TThreadProcedure);overload;
在后台作业中,直接调用 RunInMainThread 函数就可以将附加的函数代码运行在主线程并等待其返回:
procedure RunInMainG(AData: Pointer); begin ShowMessage('您好,主线程全局函数版本(当前线程ID='+IntToStr(GetCurrentThreadId)+',主线程ID='+IntToStr(MainThreadId)+').'); end; procedure TForm1.RunInMainO(AData: Pointer); begin ShowMessage('您好,主线程对象成员函数版本(当前线程ID='+IntToStr(GetCurrentThreadId)+',主线程ID='+IntToStr(MainThreadId)+').'); end; procedure TForm1.DoRunInMainThreadJob(AJob: PQJob); begin {$IFDEF UNICODE} RunInMainThread( procedure begin ShowMessage('您好,主线程匿名函数版本(当前线程ID='+IntToStr(GetCurrentThreadId)+',主线程ID='+IntToStr(MainThreadId)+').'); end); {$ENDIF} RunInMainThread(RunInMainG,nil); RunInMainThread(RunInMainO,nil); end;
注意,与 Post 一个主线程异步作业不同,RunInMainThread 会等待相应的函数在主线程执行完成并返回,而 Post 的主线程作业在投寄到内部队列后立即返回。
【更新级别】
可选
【特别说明】
新春小礼物,祝大家春节快乐!
在多线程中,我们与主线程交互的目的不外乎两种:
1、更新进度提示,一般我们不推荐在后台作业中频繁的更新信息,个人推荐两种方法:
(1)、主线程中定时器或定时作业获取后台进度,然后显示到界面上;
(2)、后台作业中记录每次的更新时间,然后每隔一段时间触发一个进度更新请求;
2、需要用户交互,比如选择项目或输入部分初始值,这类直接调用上面的函数执行即可。