AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?
Thema durchsuchen
Ansicht
Themen-Optionen

Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

Ein Thema von Kostas · begonnen am 3. Apr 2018 · letzter Beitrag vom 6. Apr 2018
Antwort Antwort
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 3. Apr 2018, 23:47
Delphi-Version: 10.2 Tokyo
Hallo Zusammen,

es geht um ein Android Projekt welches sich an einem DataSnap Server verbindet. Die Verbindung ist nicht stabil weil es eben ein mobiles Gerät ist.
Der Server stellen einige Methoden bereit. Ich hätte gerne einen Thread dem ich die Methode z.B.: GetAdress(PersonID) übergebe. Der Thread feuert zunächst die GetAdress. Wenn es knallt, baut er die Verbindung auf und feuer GetAdress erneut.


Gibt es eine Möglichkeit über die neue TParallel Klassen das umzusetzen?
Nach was müsste ich bitte suchen, ich finde sehr wenig Dokumentation zu dem Thema?
Ich habe die Beispiel zu TTask.Run, TTask.Future und TParallel.For angeschaut dann gibt es noch ein Join aber viel mehr konnte ich noch nicht finden.

Gruß Kostas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 4. Apr 2018, 02:41
TParallel ist dafür gut mehrere "zusätzliche" Threads zu verwalten -> Eine Aufgabe automatisch auf viele Threads verteilen.

Du willst nur "einen" Thread haben, da wäre TThread oder eben moderner TTask eines der Mittel deiner Wahl.
http://docwiki.embarcadero.com/RADSt...amming_Library


Alternativ nur ein/einige ständig laufende(r) Thread(s), dem/denen du z.B. über eine Liste Aufgaben übergibst, die nacheinander da rausgeholt und abgearbeitet werden.
Im Prinzip übernimmt das TTask für dich.
$2B or not $2B

Geändert von himitsu ( 4. Apr 2018 um 02:44 Uhr)
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 4. Apr 2018, 09:00
Hi himitsi,
Meine Auflistung der Beispiele kommen zufällig aus ganau deinem Link. Die habe ich also alle abgearbeitet. So wie dich einschätze hast du mir schon die richtigen Tipp gegeben mit: Ein Thread der eine Queue abarbeiten kann. Demnach ist TParallels dafür nicht geeignet. Das "normale" Zeug mit TThread ist richtig kompliziert. Kennst du zufällig ein Beispiel in dem gezeigt wird wie ein Thread als Parameter eine Prozedur übergeben bekommt die ebenfalls Paramerer enthält?. Alle Beispiele die ich gefunden habe sind mit Anonyme Methoden ohne Parameter. Ich würde gerne dem Thread die Methode z.B.: GetAdress (adressID) zum ausführen
übergeben.

Gruß Kostas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 4. Apr 2018, 10:11
Eine der "billigsten" Varianten mit TThread wäre z.B.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
begin
  Button1.Caption := '...';
  S := 'A B C';
  TThread.CreateAnonymousThread(procedure
    begin
      Sleep(3000);
      S := ReverseString(S);
      //...
      TThread.Synchronize(nil, procedure
        begin
          Button1.Caption := S;
        end);
    end).Start;
end;
Aber das Erstellen/Starten eines Thread verbraucht einiges an Systemressourcen (ist langsam).

Mit TTask kann man das ähnlich machen.
Aber dort kann man einen eigenen ThreadPool angeben oder den globalen ThreadPool nutzen, wobei diese Threads wiederverwendet und nicht immer neu erstellt werden.
Auch kann man die maximale Anzahl gleichzeitiger Tasks steuern und es gibt NotifyEvents, wenn einer/alle Tasks fertig sind und das Teil kann noch viel mehr.

TTask, TFuture, TParallel usw. bassieren aud TThread und erweitern es um weitere Features, die du dann nicht selber implementieren mußt, vor allem in Bezug auf eine bessere Verwaltung der Thread-Ressourcen.
TFeature ist ein TTask mit "tu was" und zusätzlich einem Delphi-Referenz durchsuchenTFeature.GetValue (gib mit das Ergebnis und warte notfalls, falls noch nicht fertig).

Du kannst z.B. selber eine ArbeitsListe für einen/mehrere Threads verwalten.
Delphi-Quellcode:
var
  List: TThreadList<string>;

procedure TDeinWorkerThread.Execute;
var
  LockedList: TList<string>;
  Value: string;
begin
  while not Terminated do begin
    Value := '';
    LockedList := List.LockList;
    try
      if LockedList.Count > 0 then begin
        Value := LockedList[0];
        LockedList.Delete(0);
      end;
    finally
      List.UnlockList;
    end;
    if Value <> 'then begin
      Sleep(3000);
      Value := ReverseString(Value);
      //...
      Synchronize(procedure
        begin
          Form10.Button1.Caption := Value;
        end);
    end else
      Sleep(100);
  end;
end;
Und dann fänst du auch noch an die Behandlung zu optimieren usw.

Oder eben die TTask oder TFeature, wo dafür schon Einiges eingebaut ist.
$2B or not $2B
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 4. Apr 2018, 13:40
Hallo himitsu,

mal sehen ob ich dich richtig verstanden habe. In beiden deiner Beispiele ist die Methode innerhalb des Threads verankert und wird ausgeführt. Daraus entnehme ich, es ist nicht möglich die Methode ReverseString(s) dem Thread zu übergeben. Für mein Projekt bedeutet das, wenn wir bei CreateAnonymousThread bleiben wollen, ich müsste jede Methode die der DataSnap Server bereitstellt umkapseln mit dem CreateAnonymousThread?

Also etwa so:


//Jede DataSnap Methode muss ich also so verpacken. Ich kann die DataSnap Methode einem Thread nicht übergeben!
Delphi-Quellcode:
procedure GetAdress_ViaThread(const AdressID: integer);
begin
  TThread.CreateAnonymousThread(procedure
    begin
      CheckDataSnapConnection;
       
      if FutureDSConneced.value //Thread wird blockiert bis Antwort kommt. FutureDSConneced ist eine globale public Variable vom Typ FutureDSConneced: IFuture<boolean>;
      then GetAdress(AdressID);
    end).Start;
end;
Delphi-Quellcode:
procedure TForm1.CheckDataSnapConnection;
begin
  FutureDSConneced := TTask.Future<boolean>(
    function:boolean
    begin
      result := false;
      
      try
        dm1.DSRestConnection1.TestConnection();
        result := true;
// dm1.DSRestConnection1.Reset;

      except
        on E: Exception do
        begin
          HandleException(E);
        end;

      end;
    end);
end;

Gruß Kostas
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 5. Apr 2018, 17:33
Hallo himitsu,

über diesen Ansatz versuche ich gerade TThreadProcedure in eine TQueue zu schreiben mit der Absicht, dass die Proceduren sequenziell ausgeführt werden können.
Doch die Proceduren werden nicht ausgeführt. Kannst du erkennen warum?



Delphi-Quellcode:

  private
    { Private-Deklarationen }
    var ProcQuere: TQueue<TThreadProcedure>;
    procedure ExecuteQueue;
    procedure Methode1InQueue;
    procedure Methode2InQueue;
  public
    { Public-Deklarationen }
  end;

  
  
procedure TForm1.FormCreate(Sender: TObject);
begin
  ProcQuere := TQueue<TThreadProcedure>.Create;
  ExecuteQueue;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  ProcQuere.Clear;
  ProcQuere.Free;
end;

procedure TForm1.btMethode1Click(Sender: TObject);
begin
  Methode1InQueue;
end;

procedure TForm1.btMethode2Click(Sender: TObject);
begin
  Methode2InQueue;
end;


procedure TForm1.ExecuteQueue;
begin
  TThread.CreateAnonymousThread(procedure
  var proc: TThreadProcedure;
  begin
    while not Application.Terminated do begin //Endlosschleife bis App beendet wird
      if ProcQuere.Count <> 0 then
      begin
        proc := ProcQuere.Dequeue();
        proc();
      end;
    end;
  end).Start;

end;
  
procedure TForm1.Methode1InQueue;
begin
  ProcQuere.Enqueue(procedure
    begin
      TThread.Synchronize(TThread.CurrentThread,
        procedure
        begin
          mo1.Lines.Add('Methode1InQueue');
        end);
    end);

end;

procedure TForm1.Methode2InQueue;
begin
  ProcQuere.Enqueue(procedure
    begin
      TThread.Synchronize(TThread.CurrentThread,
        procedure
        begin
          mo1.Lines.Add('Methode2InQueue');
        end);
    end);

end;

Gruß Kostas

Geändert von Kostas ( 6. Apr 2018 um 14:12 Uhr)
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Ist es möglich über TParallel eine Procedure zum ausführen zu übergeben?

  Alt 6. Apr 2018, 14:13
HALT hat sich erledigt.

Die Methode muss natürlich manuell ausgeführt werden.


Delphi-Quellcode:
procedure TForm1.ExecuteQueue;
begin
  TThread.CreateAnonymousThread(procedure
  var proc: TThreadProcedure;
  begin
    while not Application.Terminated do begin //Endlosschleife bis App beendet wird
      if ProcQuere.Count <> 0 then
      begin
        proc := ProcQuere.Dequeue();
        proc(); // Die Methode muss natürlich manuell ausgeführt werden.
      end;
    end;
  end).Start;

end;
  Mit Zitat antworten Zitat
Antwort Antwort


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 01:01 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