Delphi在不阻塞主线程的情况下获取TTask.IFuture?

时间:2017-11-26 10:58:32

标签: delphi task future

在下面的示例中(来自Embarcadero的手册),MyValue将在3秒后检索到。但是,主要的gui线程将被MyValue:= FutureObject.Value阻塞;等待结果的电话。 如果未来代码需要很长时间,让我们说30秒,Windows会在程序标题中显示“......没有响应”。 那么当它阻止主要的gui线程时,目的是什么呢? 有没有其他方法可以在不阻塞主gui线程的情况下获得结果?

FutureObject := TTask.Future<Integer>(function: Integer
    begin
        Sleep(3000);
        Result := 16;
    end);
// …
MyValue := FutureObject.Value;

2 个答案:

答案 0 :(得分:2)

按照设计,IFuture.Value属性会阻塞调用线程,直到另一个线程分配一个值。因此,如果您在主线程中读取Value,它将阻止主线程,直到值准备好。

如果你必须在主要线程中不加阻塞地阅读Value,你可以:

  • 使用计时器或其他异步机制定期查询IFuture.Status属性,以检查IFuture何时准备好在实际读取之前提供值。

  • 在主线程准备就绪时将并行任务信号作为主线程,然后主线程可以读取其信号处理程序中的Value

答案 1 :(得分:1)

我知道可能会晚一点,但是我通过创建一个TTask解决了这个问题, MyValue:= FutureObject.Value

FutureObject := TTask.Future<Integer>(function: Integer
begin
    Sleep(3000);
    Result := 16;
end);
// …
TTask.Run(Procedure begin
MyValue := FutureObject.Value;
end);