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