【问题标题】:Delphi getting TTask.IFuture without blocking main thread?Delphi 在不阻塞主线程的情况下获得 TTask.IFuture?
【发布时间】:2019-08-05 22:23:26
【问题描述】:

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

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

【问题讨论】:

  • 如果您需要知道,那么您需要等待。也许您正在寻找一种事件驱动的方法。一些上下文会有所帮助。我建议你买一本关于并行处理的书并学习这些概念。不需要基于delphi,其他oop语言的概念是一样的。

标签: delphi task future


【解决方案1】:

根据设计,IFuture.Value 属性会阻塞调用线程,直到另一个线程分配一个值。所以,如果你在主线程中读取Value,它将阻塞主线程,直到一个值准备好。

如果你必须在主线程中读取Value而不阻塞,你可以:

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

  • 让并行任务在主线程就绪时发出信号,然后主线程可以在其信号处理程序中读取Value

【讨论】:

  • 谢谢你的回答,因为它很好地解释了我。
  • 一旦你准备好了就开始向主线程发信号,那么使用未来就没有任何意义了。
【解决方案2】:

我知道这可能有点晚了,但我通过创建一个 TTask 来解决它 MyValue := FutureObject.Value

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多