AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

Ein Thema von DeddyH · begonnen am 7. Dez 2017 · letzter Beitrag vom 8. Dez 2017
Antwort Antwort
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
26.559 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#1

Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 09:43
Ich habe gerade eine kleine Denkblockade . Folgende Situation: ich rufe Daten von einem REST-Server (auch von mir) ab. Da die Datenmengen auch mal etwas größer werden können, habe ich mir eine Art Pagination einfallen lassen, d.h. der Server schickt mir einen Response mit maximal 100 Datensätzen, welcher zusätzlich ein Objekt mit den Feldern offset, count und hasmoredata enthält. Damit kann ich am Client die passende Route errechnen, um die nächsten Datensätze abzurufen. Das funktioniert wie die Wutz, allerdings läuft das im Moment auf dem Client alles im Mainthread ab, der ist dann natürlich blockiert. Daher bin ich auf die Idee gekommen, jede Abfrage und anschließende Abarbeitung in einen Thread zu packen, habe aber Probleme bei der Implementation. Der derzeitige Code hat sinnbildlich den folgenden Aufbau:
Delphi-Quellcode:
procedure TMyClass.GetData;
var
  MoreData: Boolean;

  procedure ReceiveData;
  var
    Response: IResponse;
  begin
    Response := GetDataFromServer;
    DoSomeGreatWork;
    MoreData := Response.HasMoreData;
  end;

begin
  repeat
    ReceiveData;
  until not MoreData;
end;
Wie schon gesagt ist angedacht, ReceiveData in einen Thread auszulagern, aber ohne dass die Schleife vorzeitig verlassen wird. Mir fällt da einfach keine elegante Lösung ein, daher bitte ich um Vorschläge.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.699 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:02
So?

Delphi-Quellcode:
TWorkThread = class(TThread);
  procedure Execute; override;
end;

procedure TWorkThread.Execute;
begin
  DoSomeGreatWork;
end;

procedure TMyClass.GetData;
var
  Threads: TList<TThread>;
  i: integer;
  procedure ReceiveData;
  var
    Response: IResponse;
    Thread: TWorkThread;
  begin
    Response := GetDataFromServer;
    Thread := TWorkThread.Create;
    Thread.Resume;
    Threads.Add(Thread);
    MoreData := Response.HasMoreData;
  end;
begin
  Threads := TList<TThread>.Create;
  repeat
    ReceiveData;
  until not MoreData;

  // Wait for threads to finish
  for i := 0 to Threads.Count - 1 do
  begin
    Threads[i].WaitFor;
    Threads[i].Free;
  end;

  // Do further work
  ...

  Threads.Free;
end;
(Keine Ahnung, ob ich die Generics richtig verwendet habe)
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
4.622 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:03
Du verlegst die Schleife in den gleichen Thread und feuerst ein Event wenn die Daten da sind.
GetData erstellt nur den Thread und kehrt danach direkt zurück.
Der Caller wartet dann auf das Event.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
26.559 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#4

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:14
Mein Problem ist die zeitliche Abfolge. Ich möchte ja gerne das Abholen der Daten bereits in den Thread verlegen, weiß aber erst danach, ob es noch weitere Daten gibt. Ich müsste wohl also eine Art "geschicktes Locking" (TMonitor?) einbauen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.699 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:30
Aber wenn du eh auf die Abarbeitung der Schleife warten musst, dann hast du ja nichts gewonnen, wenn du das Abohlen der Daten mit in den Thread verlagerst. Dann kannst du es auch gleich im Hauptthread machen. Kannst du vielleicht noch mal genauer erklären, was du machen willst?
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
1.418 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:44
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils,
  System.Threading;

type
  IResponse = interface
    ['{E705E40C-9BC2-41EE-AE4B-2E1D514395E9}']
    function HasMoreData: Boolean;
  end;

  TResponse = class(TInterfacedObject, IResponse)
  private
    class var
      FCounter: Integer;
  public
    function HasMoreData: Boolean;
  end;

  TMyClass = class
    procedure GetData;
    function GetDataFromServer: IResponse;
    procedure DoSomeGreatWork;
  end;

procedure TMyClass.DoSomeGreatWork;
begin
  Writeln('Make Work Great Again!');
end;

procedure TMyClass.GetData;
var
  MoreData: Boolean;

  procedure ReceiveData;
  var
    Response: IResponse;
  begin
    Response := GetDataFromServer;
    DoSomeGreatWork;
    MoreData := Response.HasMoreData;
  end;

begin
  repeat
    ReceiveData;
    Writeln('HasMoreData: ', MoreData);
  until not MoreData;

  Writeln('Fix und fertig!');
end;

function TMyClass.GetDataFromServer: IResponse;
begin
  Result := TResponse.Create;
  Sleep(50);
end;

function TResponse.HasMoreData: Boolean;
begin
  Result := True;
  Inc(FCounter);
  if FCounter = 100 then
    Result := False;
end;

procedure Main;
begin
  TTask.Run(
    procedure
    var
      MyObject: TMyClass;
    begin
      MyObject := TMyClass.Create;
      try
        MyObject.GetData;
      finally
        MyObject.Free;
      end
    end);
end;

begin
  try
    Main;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
4.622 Beiträge
 
Delphi 2010 Professional
 
#7

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:47
Mein Problem ist die zeitliche Abfolge. Ich möchte ja gerne das Abholen der Daten bereits in den Thread verlegen, weiß aber erst danach, ob es noch weitere Daten gibt. Ich müsste wohl also eine Art "geschicktes Locking" (TMonitor?) einbauen.
Hast du gesehn was ich geschrieben hab? Damit erledigt sich das doch.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
1.418 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#8

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 10:51
Das Daten holen und Verarbeiten kannst du natürlich auch Trennen.
Das Verarbeiten wiederum kann nochmals parallelisiert werden, falls notwendig.

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils,
  System.Threading,
  System.Generics.Collections;

type
  IResponse = interface
    ['{E705E40C-9BC2-41EE-AE4B-2E1D514395E9}']
    function HasMoreData: Boolean;
  end;

  TResponse = class(TInterfacedObject, IResponse)
  private
    class var
      FCounter: Integer;
  public
    function HasMoreData: Boolean;
  end;

  TMyClass = class
  private
    FRespones: TList<IResponse>;
  public
    constructor Create();
    destructor Destroy; override;
    procedure GetData;
    function GetDataFromServer: IResponse;
    procedure DoSomeGreatWork(const AResponse: IResponse);
  end;

constructor TMyClass.Create;
begin
  inherited;
  FRespones := TList<IResponse>.Create;
end;

destructor TMyClass.Destroy;
begin
  FRespones.Free;
  inherited;
end;

procedure TMyClass.DoSomeGreatWork;
begin
  Writeln('Make Work Great Again!');
end;

procedure TMyClass.GetData;
var
  MoreData: Boolean;
  Response: IResponse;
begin
  repeat
    Response := GetDataFromServer;
    FRespones.Add(Response);
    MoreData := Response.HasMoreData;
    Writeln('HasMoreData: ', MoreData);
  until not MoreData;

  for Response in FRespones do
  begin
    DoSomeGreatWork(Response);
  end;

  Writeln('Fix und fertig!');
end;

function TMyClass.GetDataFromServer: IResponse;
begin
  Result := TResponse.Create;
  Sleep(50);
end;

function TResponse.HasMoreData: Boolean;
begin
  Result := True;
  Inc(FCounter);
  if FCounter = 100 then
    Result := False;
end;

procedure Main;
begin
  TTask.Run(
    procedure
    var
      MyObject: TMyClass;
    begin
      MyObject := TMyClass.Create;
      try
        MyObject.GetData;
      finally
        MyObject.Free;
      end
    end);
end;

begin
  try
    Main;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
26.559 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#9

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 7. Dez 2017, 11:00
Sorry, wie gesagt: ich bin heute irgendwie verpeilt. Primär geht es mir lediglich um eine reagierende Oberfläche, ich schaue mir den Code jetzt erst einmal genauer an. Danke an alle.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
3.697 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#10

AW: Sequentielle Abarbeitung mit Threads - Anregungen erwünscht

  Alt 8. Dez 2017, 10:40
Pipeline?

Soll jetzt keine Werbung sein...

Aber ich mache es so: LINK

Mavarik
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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:

Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2017 by Daniel R. Wolf