AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte AsyncCalls 2.91 - Asynchrone Funktionsaufrufe in Delphi
Thema durchsuchen
Ansicht
Themen-Optionen

AsyncCalls 2.91 - Asynchrone Funktionsaufrufe in Delphi

Ein Thema von jbg · begonnen am 15. Dez 2006 · letzter Beitrag vom 17. Mär 2009
Antwort Antwort
Seite 2 von 3     12 3      
jbg
Registriert seit: 12. Jun 2002
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, 46x aufgerufen)
 
jbg

 
Delphi 10.1 Berlin Professional
 
#11
  Alt 27. Sep 2008, 19:27
Zitat von DeddyH:
Das heißt, nur mit Delphi 2009 nutzbar?
Ja. Aber der Code is mit einem IFDEF Umgeben, so dass die "alten" Funktionen für Delphi 5 bis 2007 nutzbar bleiben.
Andreas aka AHUser aka jbg
  Mit Zitat antworten Zitat
jbg

 
Delphi 10.1 Berlin Professional
 
#12
  Alt 29. Sep 2008, 09:53
Nun hat mich der Delphi 2009 vor den Kopf gestoßen. AsyncCalls 2.9 ist nicht mit Delphi 2009 nutzbar, da bei einem "Make Project" ein interner Compiler Fehler auftritt. Und dass man seine Projekte immer mit "Build Project" erzeugt, halt ich für eine Zumutung.
Andreas aka AHUser aka jbg
  Mit Zitat antworten Zitat
Assertor

 
Turbo C++
 
#13
  Alt 29. Sep 2008, 10:03
Hi,

Zitat von jbg:
Nun hat mich der Delphi 2009 vor den Kopf gestoßen. [...] nicht mit Delphi 2009 nutzbar, da [...] ein interner Compiler Fehler auftritt.
Da muß wohl noch an der Stabilität des neuen Compiler gearbeitet werden

Übrigens mal ein großes, dickes

Danke

für Deine gute Arbeit!

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
jbg

 
Delphi 10.1 Berlin Professional
 
#14
  Alt 29. Sep 2008, 10:19
[quote="Assertor"]Da muß wohl noch an der Stabilität des neuen Compiler gearbeitet werden
Bei der neuen Version 2.91, die ab jetzt verfügbar ist, habe ich sämtliche Generics auskommentiert. Ich hoffe, dass das "Delphi 2009 Update 1" bald kommt, da Generics so für mich nicht wirklich nutzbar sind. Da ich nicht gerne russisches Roulette spiele.

Zitat:
Übrigens mal ein großes, dickes Danke
Danke.
Andreas aka AHUser aka jbg
  Mit Zitat antworten Zitat
Assertor

 
Turbo C++
 
#15
  Alt 2. Okt 2008, 15:25
Hi,

so und um jetzt mal dem theoretischen Teil der Forschung und Entwicklung etwas mehr Breite zu verpassen, hier eine Thread Library für Delphi von Primoz, dem Autoren von OmniXML:

OmniThreadLibrary

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
BloodySmartie
 
#16
  Alt 1. Dez 2008, 17:13
Ich bin mir noch nicht ganz sicher ob es nicht doch an mir liegt, aber ich glaube ich habe einen Bug gefunden.

In der Execute-Prozedur eines Threads passiert u.a. folgendes:
Delphi-Quellcode:
  c:=qry.RecordCount;
  setlength(self.Machines,c);
  qry.First;

  for I := 0 to c - 1 do begin
    tmps:=utf8toansi(qry.FieldByName('phonenumber').AsString);
    p:=localFindMachine(tmps);
    EnterMainThread;
    try
      p^.isDeleted:=true;
      p^.isactive:=false;
    finally
      LeaveMainThread;
    end;
    qry.Next;
  end;
Soweit ich das nun verfolgen konnte, hat c zunächst den erwarteten Wert - nämlich die Zahl der Datensätze aus meiner SQL-Abfrage. Nach LeaveMainThread hat c aber den Wert 0.

Vielleicht habe ich aber auch die Funktionsweise von EnterMainThread / LeaveMainThread falsch verstanden.
  Mit Zitat antworten Zitat
jbg

 
Delphi 10.1 Berlin Professional
 
#17
  Alt 1. Dez 2008, 17:50
Wo hast du c denn deklariert?
Wird noch von woanders darauf zu gegriffen?
"for I := 0 to c - 1 do begin" Der Compiler braucht c nach dieser Zeile nicht mehr, da die Schleife rückwärts laufen kann. Der Debugger weiß das aber nicht und zeigt möglicherweise den Inhalt an, der zufälligerweise im CPU Register steht, das vorher für c benutzt wurde.
Andreas aka AHUser aka jbg
  Mit Zitat antworten Zitat
BloodySmartie
 
#18
  Alt 1. Dez 2008, 17:59
c ist lokal deklariert und ich greife weiter unten nochmal in einer Verzweigung darauf zu, in der ich Prüfe, ob c größer als 0 ist. Das schlug dauernd fehl, so bin ich auf das Problem gestoßen.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

 
Delphi 7 Enterprise
 
#19
  Alt 1. Dez 2008, 18:02
Dein Compiler dürfte dir eine Warnung ausgeben: "c nach Schleifendurchlauf undefiniert" oder so ähnlich
  Mit Zitat antworten Zitat
BloodySmartie
 
#20
  Alt 1. Dez 2008, 18:06
Eine solche Warnung bekomme ich auch nicht. Das verstehe ich jetzt sowieso nicht. Warum sollte mein Compiler denn c einfach wegwerfen, nur weil ich es in der Schleife verwende? besonders, wo es ein paar Zeilen weiter unten ja noch gebraucht wird. Das habe ich auch vorher noch nie beobachtet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz