Einzelnen Beitrag anzeigen

jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 

AsyncCalls 2.91 - Asynchrone Funktionsaufrufe in Delphi

  Alt 15. Dez 2006, 00:10
Mit meiner neuesten Erschaffung (AsyncCalls) kann man nun sehr leicht und ohne großen Aufwand mehreren Funktionen und Methoden zur gleichen Zeit ausführen und diese auch noch synchronisieren. Dazu ist nicht mehr notwendig, als eine der AsyncCall() Funktionen aufzurufen. Diese liefert dann ein IAsynCall Interface zurück mit dem der asynchrone Funktionsaufruf wieder synchronisiert werden kann. Da es sich um ein Interface handelt, wird beim Verlassen der Funktion/Methode auf alle noch ausstehenden asynchronen Funktionen gewartet.

Homepage, Download und Beschreibung

Beispielcode (Einlesen von drei Verzeichnissen in asynchronen Funktionen):
Delphi-Quellcode:
function TFormMain.DoSomething(Value: TObject): Integer;
begin
  Result := 0;
end;

procedure TFormMain.Button3Click(Sender: TObject);
var
  Value: Integer;
begin
  // TAsyncCalls.Invoke<TObject>(DoSomething, nil); wegen internal compiler error nicht mehr funktionsfähig

  TAsyncCalls.Invoke(procedure
  begin
    Value := 10;
    TAsyncCalls.VCLInvoke(procedure
    begin
      ShowMessage('Der Werk könnte ungleich 10 sein: ' + IntToStr(Value));
    end);
    Value := 20;
    TAsyncCalls.VCLSync(procedure
    begin
      ShowMessage('Der Wert ist 20: ' + IntToStr(Value));
    end);
    Value := 30;
  end).ForceDifferentThread;

  Sleep(1000);
end;
Delphi-Quellcode:
{ Die cdecl Funktion GetFiles() besitzt zwei Parameter vom Typ string und object, die hier ganz normal deklariert werden. }
procedure GetFiles(const Directory: string; Filenames: TStrings); cdecl;
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);
    Windows.FindClose(h);
  end;
end;

procedure TFormMain.ButtonGetFilesClick(Sender: TObject);
var
  Dir1, Dir2, Dir3: IAsyncCall;
  Dir1Files, Dir2Files, Dir3Files: TStrings;
begin
  Dir1Files := TStringList.Create;
  Dir2Files := TStringList.Create;
  Dir3Files := TStringList.Create;
  ButtonGetFiles.Enabled := False;
  try
    { Die beiden Parameter der GetFiles() Funktion werden mittels eines const array of const übergeben }
    Dir1 := AsyncCall(@GetFiles, ['C:\Windows', Dir1Files]);
    Dir2 := AsyncCall(@GetFiles, ['D:\Html', Dir2Files]);
    Dir3 := AsyncCall(@GetFiles, ['E:', Dir3Files]);

    { Warten bis die beiden asynchronen Funktion beenden sind. Während dieser Zeit dem die UI nicht einfrieren lassen }
    while AsyncMultiSync([Dir1, Dir2], True, 10) < 0 do
      Application.ProcessMessages;
    Dir3.Sync; // Auf die Beendigung der Dir3 Funktion warten

    MemoFiles.Lines.Assign(Dir1Files);
    MemoFiles.Lines.AddStrings(Dir2Files);
    MemoFiles.Lines.AddStrings(Dir3Files);
  finally
    ButtonGetFiles.Enabled := True;
    Dir3Files.Free;
    Dir2Files.Free;
    Dir1Files.Free;
  end;
end;
Angehängte Dateien
Dateityp: zip asynccalls_138.zip (32,2 KB, 45x aufgerufen)
  Mit Zitat antworten Zitat