http://blog.csdn.net/henreash/article/details/41349145
上篇文章讲了使用TTask快速开发同时运行多个任务的应用程序,减少瓶颈。接下来讲解ITask的子接口IFuture。
IFuture
IFuture给TTask提供了一个机制,让我们可以传递返回特定类型的函数(使用了泛型,类型由<T>决定)。使用IFuture实例,运行一个任务,同时让主线程继续执行到我们需要任务运行结果处。使用这种机制可以把代码块按优先级执行,同时也保证在需要的时候获取到任务的运行结果。
范例
要在Future中获取一个值,首先定义这个值得类型,运行任务,并获取值。为了展示这个过程,下面编写一个无实际意义的范例(但演示了如何使用这个特性),后面会一步一步解释。
var
OneValue: IFuture <Integer>;
OtherValue: Integer;
Total: Integer;
begin
OneValue := TTask.Future<Integer>(function: Integer
begin
Result := ComputeSomething;
Sleep(1000); // delay to show status
end);
Memo1.Lines.Add(TRttiEnumerationType.
GetName<TTaskStatus>(OneValue.Status));
OtherValue := ComputeSomething;
Memo1.Lines.Add(TRttiEnumerationType.
GetName<TTaskStatus>(OneValue.Status));
Total := OtherValue + OneValue.Value;
Memo1.Lines.Add(TRttiEnumerationType.
GetName<TTaskStatus>(OneValue.Status));
// result
Memo1.Lines.Add(Total.ToString);
end;
代码输出如下图所示:
代码关键点
首先,使用TTask.Future<T>定义返回值的类型,接着传递一个匿名方法,返回实际的值。(这里从ComputeSomething方法返回一个整数)
将TTask.Future返回的IFuture类型实例赋给OneValue变量。
OneValue := TTask.Future<Integer>(function: Integer
begin
Result := ComputeSomething;
Sleep(1000); // delay to show status
end);
匿名方法中的Sleep操作没有什么实际意义,但可以使程序运行后,得到OneValue.Status的不同值:WaitingToRun,Running,Completed。
下面的代码,查询OneValue当前状态。下面的代码将枚举类型的状态转换为字符串类型:
TRttiEnumerationType.GetName<TTaskStatus>(OneValue.Status)
由于任务正准备执行,第一个返回值是WaitingToRun。首次状态查询后,调用ComputeSomethis任务:
OtherValue := ComputeSomething;
接着查看OneValue的状态,已经变为了运行中(由于Sleep的时间比ComputeSomething执行时间长)。
注意!是否意味着需要不停的检查状态来确定是否已经可以获取结果值了呢?当然不是。
Total := OtherValue + OneValue.Value;
这行代码告诉OneValue我们需要他的值。如果任务执行完毕则将值返回,否则将阻塞等待IFuture完成。这让开发人员很轻松。
这个IFuture可以运行你设置的过程,并在完成后返回。是另外一种节省时间提高效率的方式。