频道分类

delphi 使用并行库中的TTask

作者:admin 来源: 日期:2020/3/1 16:27:29 人气: 标签:

 
本文章介绍了Delphi XE7使用并行库中的TTask  ,上篇文章学习使用System.Threading单元提供的并行编程和TParallel.For提升循环的执行效率。当需要运行多任务而不是一个循环时,也可以使用并行方式。
  使用System.Threading.TTask和System.Threading.ITask可方便的串行执行几个进程.使用TTask类创建任务,使用ITask接口实例管理进程的交互。在代码完成处理前可以使用WaitForAll或WaitForAny等待任务完成.
例如,假设有两个任务A和B.如果一个任务用时3秒,另一个用时5秒,用户得到运行结果需要多长时间呢?
串行 (未使用TTask / ITask) = 8秒.
使用TTask.WaitForAll = 5秒
使用TTask.WaitForAny = 3秒
根据任务的不同,获取返回值的效率可显著提高.下面看看WaitForAll范例.
Users System.Threading, System.SyncObjs
procedure TFormThreading.MyButtonClick(Sender: TObject);
var
tasks: array of ITask;
value: Integer;
begin
Setlength (tasks ,2);
value := 0;
tasks[0] := TTask.Create (procedure ()
   begin
     sleep (3000); // 3 seconds
     TInterlocked.Add (value, 3000);// users System.SyncObjs
   end);
tasks[0].Start;
tasks[1] := TTask.Create (procedure ()
   begin
     sleep (5000); // 5 seconds
     TInterlocked.Add (value, 5000);// users System.SyncObjs
   end);
tasks[1].Start;
TTask.WaitForAll(tasks);
ShowMessage ('All done: ' + value.ToString);
end;
上例使用ITask数组管理一系列任务.结果返回8000,尽管共Sleep了8秒,但前3秒是并行运行的,2秒后第二个任务也完成了,相当于前3秒两个任务同时运行;注意这里并没有创建自定义线程以及管理返回值。
当然提升获取返回值程序的执行效率是很有用的,也可使用TTask执行后台任务避免UI阻塞,要实现这个目标,只需启动一个单独的任务并运行,例如:
procedure TFormThreading.Button1Click(Sender: TObject);
var
aTask: ITask;
begin
// not a thread safe snippet
aTask := TTask.Create (procedure ()
   begin
     sleep (3000); // 3 seconds
     ShowMessage ('Hello');
   end);
aTask.Start;
end;
第二个范例可让用户多次点击按钮,调用多次ShowMessage,实际开发中可以使用这种高效的方式运行实际任务。这也是异步编程的范例:启动任务,执行其他代码后,处理任务的返回结果。
ITask
ITask提供了一系列方法和属性控制任务,包括启动(Start)、等待(Wait)、取消(Cancel)、获取状态(Created, WaitingToRun, Running, Completed, WaitingForChildren, Canceled, Exception)。ITask是一个接口,可创建TTask类实例后,赋给ITask变量,增加框架的可扩展性.
根据测试,TTask相当于启动了一个子线程,上篇文章指出是基于一个线程池的。