AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Nur nacheinander abarbeiten bei http get

Ein Thema von Markus Effenberger · begonnen am 9. Mär 2019 · letzter Beitrag vom 15. Mär 2019
Antwort Antwort
Seite 1 von 2  1 2   
Markus Effenberger

Registriert seit: 2. Jul 2014
38 Beiträge
 
Delphi 10.3 Rio
 
#1

Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 20:36
Guten Abend Miteinander

Das Projekt nutzt einen idHTTPServer, um Daten bei entsprechender Anfrage an einen Client zu senden.

Um die Fertigstellung des Projektes etwas zu beschleunigen, möchte ich das Ereignis HTTPServerCommandGet so abändern, dass es niemals durch Threads parallel abgearbeitet wird, sondern immer alle Get-Requests nacheinander abgearbeitet werden. Das Problem ist: Es finden GUI-Zugriffe und Tabellen-Zugriffe statt und das crasht natürlich, wenn das parallel passiert. Und das tut es leider, weil ja jeder request in dem idHTTPServer einen eigenen Thread erzeugt.

Ist eine Critical Section bereits eine Lösung? Oder gibt es eine andere Möglichkeit?

Code:
procedure TfrmMain.HTTPServerCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);

  Var Dateiname, Antwort : string;
begin

(...)

//Hier soll bitte gewartet werden, bis kein anderer HTTPServerCommandGet mehr unterhalb dieser Position abgearbeitet wird. Ein paar Sekunden warten ist egal.

(...)

  if ARequestInfo.Params.Values['test'] <> ''
    then begin
      AResponseInfo.ContentText := 'GO' + ARequestInfo.Params.Values['test'];
    end;

  if ARequestInfo.Params.Values['Getliste'] <> ''
    then begin
      AResponseInfo.ContentText := komplette_Tabelle_als_String('liste');
    end;

  if ARequestInfo.Params.Values['GetOberkategorie'] <> ''
    then begin
      AResponseInfo.ContentText := komplette_Tabelle_als_String('Oberkategorie');
    end;

  if ARequestInfo.Params.Values['GetPersonalliste'] <> ''
    then begin
      AResponseInfo.ContentText := komplette_Tabelle_als_String('Personalliste');
    end;

  if ARequestInfo.Params.Values['GetUnterkategorie'] <> ''
    then begin
      AResponseInfo.ContentText := komplette_Tabelle_als_String('Unterkategorie');
    end;

  if ARequestInfo.Params.Values['GetUnternehmensdaten'] <> ''
    then begin
      AResponseInfo.ContentText := komplette_Tabelle_als_String('Unternehmensdaten');
    end;

end;
Ist die Frage verständlich?
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
1.062 Beiträge
 
#2

AW: Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 20:39
Du könntest die ankommenden Anfragen in irgendeine Liste packen die alle notwendigen Informationen bereit hält und im Hintergrund abgearbeitet wird.

Irgendwie sowas. Aber in jedem Fall mit einer Art Queue, sodass nicht 10 Threads hintereinander erstellt werden, obwohl die vorherigen 5 noch nicht fertig sind.
So, dass immer nur ein Thread zur selben Zeit arbeitet.
  Mit Zitat antworten Zitat
Alt 9. Mär 2019, 20:46     Erstellt von Markus Effenberger
Dieser Beitrag wurde von fkerber gelöscht. - Grund: Inhalt durch Autor gelöscht
DieDolly

Registriert seit: 22. Jun 2018
1.062 Beiträge
 
#3

AW: Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 20:52
Das kann ich dir nicht sagen. Die Liste muss nicht einmal threadsicher sein denn dort speicherst du lediglich die Informationen, die der Thread nachher bekommen soll der gestartet wird.

Schematisch
[
0,Daten Daten Daten,2019-03-09 21-50,Daten Daten und noch mehr Strings oder so
1,Daten Daten Daten,2019-03-09 22-40,Daten Daten und noch mehr Strings oder so
2,Daten Daten Daten,2019-03-09 23-30,Daten Daten und noch mehr Strings oder so
3,Daten Daten Daten,2019-03-09 24-20,Daten Daten und noch mehr Strings oder so
]

Die wird abgearbeitet und aus den Informationen jeweils ein Thread erstellt der die eigentliche Arbeit macht.
Den Thread den du da irgendwie im Get drin hast würde ich rausnehmen. Oder Daten und GUI trennen. Dann gäbe es auch keine Fehler mehr denke ich.
  Mit Zitat antworten Zitat
Markus Effenberger

Registriert seit: 2. Jul 2014
38 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 20:56
Der vorhandene Thread soll einfach nur warten. Wie macht man das?

Die ursprüngliche Frage wurde leider nicht beantwortet.

Geändert von Markus Effenberger ( 9. Mär 2019 um 21:00 Uhr)
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
1.062 Beiträge
 
#5

AW: Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 21:01
Zitat:
Der vorhandene Thread soll einfach nur warten
Einfach gibt es nicht.

Das kann man auch nicht so einfach beantworten schätze ich, ohne auch nur ansatzweise zu wissen wie der Thread aufgebaut ist.
Von Außen sollte man einen Thread eh niemals anhalten. Denn man weiß nie, ob das zu Fehlern führt oder nicht.

Eine einfache Antwort auf deine Frage oder einen einfachen Code, um einen Thread anzuhalten, gibt es nicht.
Wenn man es richtig machen will, ist das mehr Arbeit als nur eine Zeile Code.
  Mit Zitat antworten Zitat
Markus Effenberger

Registriert seit: 2. Jul 2014
38 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 21:06
[QUOTE=DieDolly;1427431]
Zitat:
Einfach gibt es nicht.
Vielleicht weiß jemand anderes eine einfache Lösung?
  Mit Zitat antworten Zitat
Schokohase

Registriert seit: 17. Apr 2018
907 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: Nur nacheinander abarbeiten bei http get

  Alt 9. Mär 2019, 22:51
Die einfachste Art wäre die Verwendung von System.TMonitor .
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    IdHTTPServer1: TIdHTTPServer;
    procedure IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo:
        TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
  private
    FLock: TObject;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  FLock := TObject.Create;
end;

destructor TForm1.Destroy;
begin
  FreeAndNil(FLock);
  inherited;
end;

procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo:
    TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  System.TMonitor.Enter(FLock);
  try

    // hier jetzt die Abfragen bearbeiten

  finally
    System.TMonitor.Exit(FLock);
  end;
end;
Eine CriticalSection würde auch funktionieren, aber System.TMonitor ist da performanter.

Wenn du auf die GUI zugreifen musst (wieso überhaupt) dann musst du natürlich noch mit dem MainThread synchronisieren.

Geändert von Schokohase ( 9. Mär 2019 um 23:02 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.733 Beiträge
 
Delphi 2009 Professional
 
#8

AW: Nur nacheinander abarbeiten bei http get

  Alt 10. Mär 2019, 08:32
Es finden GUI-Zugriffe und Tabellen-Zugriffe statt und das crasht natürlich, wenn das parallel passiert. Und das tut es leider, weil ja jeder request in dem idHTTPServer einen eigenen Thread erzeugt.

Ist eine Critical Section bereits eine Lösung? Oder gibt es eine andere Möglichkeit?
TIdHTTPServer ist eine Multithreading-Komponente und startet einen Thread pro HTTP Verbindung. Aus dem Kontext dieses Threads wird OnCommandGet aufgerufen, und aus diesem Thread darf nur synchronisiert auf den Mainthread zugegriffen werden (mit synchronize oder mittels TThread.Queue).

Wenn der Server durch mehrere Anfragen überlastet ist, so sollte er einen passenden HTTP Responsecode zurückliefern und Behandlung des Requests beenden.

Zu blockieren ist nicht sinnvoll, denn wenn mehrere CPU Kerne untätig sind würde so nur einer verwendet.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Schokohase

Registriert seit: 17. Apr 2018
907 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: Nur nacheinander abarbeiten bei http get

  Alt 10. Mär 2019, 08:38
Zu blockieren ist nicht sinnvoll, denn wenn mehrere CPU Kerne untätig sind würde so nur einer verwendet.
Natürlich ist es nicht sinnvoll, weil man dadurch Performance vergeudet, aber die Intention des TE ist ja auch nicht die Performance der Anwendung, sondern
Um die Fertigstellung des Projektes etwas zu beschleunigen, möchte ich das Ereignis HTTPServerCommandGet so abändern, dass es niemals durch Threads parallel abgearbeitet wird, sondern immer alle Get-Requests nacheinander abgearbeitet werden.
Einzig das mit dem GUI Zugriff verstehe ich nicht, wozu der überhaupt benötigt wird.
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.733 Beiträge
 
Delphi 2009 Professional
 
#10

AW: Nur nacheinander abarbeiten bei http get

  Alt 10. Mär 2019, 09:20
gelöscht
Michael Justin

Geändert von mjustin (10. Mär 2019 um 09:22 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

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:

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