【问题标题】:result from AnonymousThread - how?AnonymousThread 的结果 - 怎么样?
【发布时间】:2018-09-27 10:36:24
【问题描述】:

我尝试做一个函数:

function MyFunction(parameter:string) : string;
begin
      TThread.CreateAnonymousThread(procedure ()
      var temp : string;
      begin
           temp := paramet;
           //some works on temp variable
           result := temp; <-- error here because it is a procedure
      end).Start;
end;

如何让MyFunction在线程结束后返回临时变量?

我也试过这样:

function MyFunction(parameter:string) : string;
vat temp : string;
begin
      TThread.CreateAnonymousThread(procedure ()
      begin
           temp := paramet;
            //some works on temp variable
      end).Start;
result := temp;
end;

以这种方式编译但返回一个空字符串。函数返回结果,不等待线程结束。

或者也许我做错了,因为我没有找到任何示例如何做到这一点?

【问题讨论】:

  • 如果MyFunction 需要在退出之前等待结果,那么使用线程根本没有意义。

标签: multithreading delphi delphi-xe5


【解决方案1】:

您不能使用新并行编程库中的 TTask.IFuture 吗? 它以非常简洁和优雅的方式完全满足您的需求:

FutureObject := TTask.Future<Integer>(function: Integer
     begin
        Sleep(3000);   // to simulate "background processing"
        Result := 16;  // result to be returned as "FutureObject.Value"
     end);

MyValue := FutureObject.Value;  // this waits for the value to be available, if it isn't yet

(示例取自这个 embarcadero wiki 页面 http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_TTask.IFuture_from_the_Parallel_Programming_Library

【讨论】:

    【解决方案2】:

    您无法从匿名线程中获得结果。 MyFunction 在线程完成之前立即返回。


    一种解决方案是使用在线程完成其工作后调用的完成处理程序。

    procedure MyProc(parameter: string; Completion: TProc<string>);
    begin
      TThread.CreateAnonymousThread(
        procedure
        var
          temp: string;
        begin
          // do something with parameter 
          temp := UpperCase(parameter);
          TThread.Synchronize(nil,
            procedure
            begin
              Completion(temp);
            end);
        end).Start;
    end;
    

    然后你这样称呼它:

      MyProc('abc',
        procedure(AValue: string)
        begin
          // do whatever you want with AValue
          Label1.Text := AValue;
        end);
    

    【讨论】:

    • 第一个解决方案返回空字符串(首先返回然后运行我的线程) 第二个解决方案:我必须添加什么单位才能使用?和 TTask 还是 ITask 类型?
    • 您错过了第一个解决方案的重点。它是过程而不是函数,如果将其转换为函数,它将无法工作,原因与第二个示例不起作用的原因相同。
    • TTask 是在 XE7 中引入的。这样你就可以在任务完成时使用回调过程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 2015-03-26
    相关资源
    最近更新 更多