PPL并行编程库01-概念
一、何为PPL,官方的解释
本教程演示如何用并行编程库(PPL)中的任务来实现应用程序 。 任务 是队列中的一些工作单元,它们在CPU时间可用时就会启动。 任务 可以并行地运行操作。它归属于有一个主线程,主线程管理此队列,并从线程池中为线程分配内存来完成任务。该 线程池 具有许多线程,具体取决于可用的CPUs数量。
官方教程目录:http://docwiki.embarcadero.com/RADStudio/Rio/en/Parallel_Programming_Library_Tutorials
http://docwiki.embarcadero.com/Libraries/Rio/en/System.Threading.TTask
二、PPL作用及执行方式
特别在长时计算和操作时,PPL可以后台多线程的方式在其内建的线程池中运行代码,同时将结果以多种方式与UI线程进行及时的沟通并通知用户做相应的操作。
(一)、以任务的方式运行PPL
1、代码模板1::以任务的立即执行方式
TTask.Run (
procedure
//var ...; // :可代变量
begin
//:1、长时计算和操作,比如Rest获取服务器数据 (可写成独立的方法function或函数procedure,但其不能再有Sender等事件通知参数)
sleep( 15000 ) ; //:模拟你的长时计算和操作
// : 2、写下面(二)、与UI线程进行交互的代码(含UI事件通知)
// ......
end ); //:返回值: ITask (TTask的接口)
2、代码模板2:以任务的非立即(准备)执行方式
var LTask : ITask ;
LTask := TTask.Create (
procedure
//var ...; // :可代变量
begin
//:1、长时计算和操作,比如Rest获取服务器数据 (可写成独立的方法function或函数procedure,但其不能再有Sender等事件通知参数)
sleep( 15000 ) ; //:模拟你的长时计算和操作
// : 2、写下面(二)、与UI线程进行交互的代码(含UI事件通知)
// ......
end ) ; //:返回值: ITask类型的LTask (TTask的接口)
LTask.Start;
3、代码模板3:以任务的Future未来方式执行
private
FIFuture: IFuture<T>;
FIFuture := TTask.Future <T> (
function : T
//var ...; // :可代变量
begin
//:1、长时计算和操作,比如Rest获取服务器数据 (可写成独立的方法function或函数procedure,但其不能再有Sender等事件通知参数)
sleep( 15000 ) ; //:模拟你的长时计算和操作
// : 2、写返回值:
Result := T;
end ); //:返回值: FIFuture: IFuture<T>; (TTask的接口ITask的子类)
// 3、然后你就不用管它了,未来,你可以在任何时候,在UI线程中,通过FIFuture.value的调用来取“未来Future”的返回值,如果FIFuture尚未计算完毕则继续计算,直到其终止 (Terminated) 后返回值,但丝毫不阻塞UI。
(二)、与UI线程进行交互的方式:
1、线程同步:
TThread.Synchronize ( nil,
procedure
begin
TDialogService.MessageDialog('执行完',TMsgDlgType.mtInformation,[TMsgDlgBtn.mbOK],TMsgDlgBtn.mbOK,-1,nil );
// ......其它UI操作及对获取的数据进行处理
end );
2、线程队列:
TThread.Queue ( nil,
procedure
begin
TDialogService.MessageDialog('执行完',TMsgDlgType.mtInformation,[TMsgDlgBtn.mbOK],TMsgDlgBtn.mbOK,-1,nil );
// ......其它UI操作及对获取的数据进行处理
end);