希望异步函数通过AsyncCalls一个接一个地执行并且无法重现演示

时间:2018-11-10 08:18:26

标签: delphi delphi-xe5

我的主要目标是运行两个耗时的功能或过程,一个运行一个函数,另一个运行完成。我当前的方法是在我从Github中的AsyncCalls Documentation.md获得的以下代码中,将第二个函数调用放置在while循环之后(假设我已经在AsyncMultiSync数组参数中将一个接口类型对象传递给了它)。另外,当我尝试运行下面提供的确切代码时,我看到线程已经完成了工作,并且执行到达了对vcl线程Memo的第一次访问,但是对备忘录的第二次访问冻结了应用程序(对于具有完全GetFiles调用中有很多文件)PS英语不是我的母语,我可能很难解释它,但是如果您将其降级为标题或MCVE,那么按照SO规则,这将是我的最后一个问题。

uses
  ..AsyncCalls;

{ Ex - 2 using global function }
function GetFiles(Directory: string; Filenames: TStrings): Integer;
var
  h: THandle;
  FindData: TWin32FindData;
begin
  h := FindFirstFile(PChar(Directory + '\*.*'), FindData);
  if h <> INVALID_HANDLE_VALUE then
  begin
    repeat
      if (StrComp(FindData.cFileName, '.') <> 0) and (StrComp(FindData.cFileName, '..') <> 0) then
      begin
        Filenames.Add(Directory + '\' + FindData.cFileName);
        if FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
          GetFiles(Filenames[Filenames.Count - 1], Filenames);
      end;
    until not FindNextFile(h, FindData);
    Winapi.Windows.FindClose(h);
  end;
  Result := 0;
end;

procedure TForm1.ButtonGetFilesClick(Sender: TObject);
var
  i: integer;
  Dir1Files, Dir2Files: TStrings;
  Dir1, Dir2 IAsyncCall;
begin
  Dir1Files := TStringList.Create;
  Dir2Files := TStringList.Create;
  ButtonGetFiles.Enabled := False;
  try
    Dir1 := TAsyncCalls.Invoke<string, TStrings>(GetFiles, 'C:\portables\autoit-v3', Dir1Files);
    Dir2 := TAsyncCalls.Invoke<string, TStrings>(GetFiles, 'E:\mySyntax-Repository-works', Dir2Files);    


    { Wait until both async functions have finished their work. While waiting make the UI
      reacting on user interaction. }
    while AsyncMultiSync([Dir1, Dir2], True, 10) = WAIT_TIMEOUT do
      Application.ProcessMessages;
{    Form1.Caption := 'after file search';}

    MemoFiles.Lines.Assign(Dir1Files);
    MemoFiles.Lines.AddStrings(Dir2Files); {-->causes freeze}
  finally
    ButtonGetFiles.Enabled := True;
    Dir2Files.Free;
    Dir1Files.Free;
  end;
end;

1 个答案:

答案 0 :(得分:0)

使用的另一种解决方案是JvThread,因为它包含评论良好的演示。可以通过onFinish事件连接多个JvThread对象,以一个接一个地启动。如果需要,可以构造许多Sync函数以与存在竞争风险的VCL线程(在线程和VCL线程之间)进行通信。并且如果需要,可以根据某些逻辑在线程执行代码内部或VCL线程中关联的Sync函数中终止它,以强制完成每个JvThread,即通过将其终止来``断开''。假设我们使用了很多全局表单字段,它与使用计时器或线程计时器首先彼此触发有什么不同?答案是没有与onFinish等效的计时器,要达到相同的效果将需要更多的精力和更少的优雅。 Omnithread对其BSD许可证有所限制,本机线程击败了DELphi的RAD精神,而Task库在XE5等较轻的安装中不可用。