AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Multithreading GUI

Ein Thema von value is NULL · begonnen am 28. Jan 2014 · letzter Beitrag vom 29. Jan 2014
Antwort Antwort
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
534 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Multithreading GUI

  Alt 28. Jan 2014, 14:30
Was hast Du für eine Delphi Version?
Könntest Du die unter Umständen freundlicherweise eintragen?
Abhängig davon fallen die Antworten unterschiedlich aus.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Multithreading GUI

  Alt 28. Jan 2014, 14:35
Was hast Du für eine Delphi Version?
Schlecht wäre es nicht.

Zitat:
{$R *.fmx}
Aber sooooo alt ist Seine vermutlich nicht.

und Diesbezüglich hat sich, in letzter Zeit, eigentlich nicht viel geändert.

[edit]
http://www.delphipraxis.net/178791-t...iremonkey.html -> siehe Ausgangsfrage, letzte Zeile
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
value is NULL

Registriert seit: 10. Sep 2010
249 Beiträge
 
#3

AW: Multithreading GUI

  Alt 28. Jan 2014, 14:50
Danke für die Antworten!
Die verwendete Delphi Version ist Delphi XE5 Architect.

Delphi-Quellcode:
procedure TMyOwnThread.Execute;
var
  i : Integer;
begin
  try
    i := 0;
    Synchronize(nil, procedure
      begin
        while i <= 20 do begin
          Form1.Memo1.Lines.Add(IntTostr(i));
          i := i + 1;
        end;
      end);
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;
Das hier klingt interessant. Ist es von Nachteil in so einer Procedure mehr zu verknüfpen? Plan wäre zB folgender:

Delphi-Quellcode:
procedure TMyOwnThread.Execute;
var
  i : Integer;
begin
   try
    i := 0;
    Synchronize(nil, procedure
      begin
        if Form1.CheckBox1.IsChecked then procedure1;
        if Form1.CheckBox2.IsChecked then procedure2;
        if Form1.CheckBox3.IsChecked then procedure3;
        if Form1.CheckBox4.IsChecked then procedure4;
        if Form1.CheckBox5.IsChecked then procedure5;
        if Form1.CheckBox6.IsChecked then procedure6;
      end);
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;
wobei es sich bei procedure1 zB um folgendes handelt:

Delphi-Quellcode:
procedure procedure1();
begin
  Form1.Memo1.Lines.Add('procedure 1 gestartet');
  //irgendwelche dinge
  Form1.Memo1.Lines.Add('procedure 1 beendet');
end;
--------------------------------------------------------------
Was ich eigentlich zu erreichen versuche, vermutlich habe ich das nicht richtig rüber gebracht,
Der User wählt diverse Dinge aus per checkbox und dementsprechend werden dann verschiedene Funktionen aufgerufen die ihre arbeit verrichten.
Jede Funktion schreibt diverse Infos in ein Memo (ich taufe dies jetzt mal "LiveLog")

Das heisst ich will natürlich:

A) Das GUI nicht zum "freeze" bringen
und B) von jeder procedure dann auf die Komponenten wie Checkboxen, TEdit's, Memo zugreifen
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Multithreading GUI

  Alt 28. Jan 2014, 15:12
Nein, so macht man das nie, niemals, nicht.

Wenn der Thread startet, dann greift der nicht mehr auf die Form zu.
Und schon gar nicht über die globale Form-Variable.

Das knallt sonst schneller als du denkst.

Und wenn du alles, was du ausführen möchtest synchronisiert ausführst, wofür dann erst einen Thread?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
value is NULL

Registriert seit: 10. Sep 2010
249 Beiträge
 
#5

AW: Multithreading GUI

  Alt 28. Jan 2014, 15:17
Prinzipiell soll er mit der GUI eigentlich nichts mehr machen können.
Das einzige was halt "schön" wäre.. wenn sich das Memo wie ein "liveLog" verhält.

Sprich: es wird eine Funktion aufgerufen die bestimmte dinge erledigt und schreibt das ins memo
Dann wird funktion2 aufgerufen und schreibt seinen Status in das Memo
usw usw ...

Der User soll halt sehen, das sich da was tut. Jetzt ist es so, das nach dem Durchlauf das Memo vollgeschrieben wird, sprich wenn schon alle Funktionen fertig sind :/
Deswegen habe ich an Threads gedacht
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Multithreading GUI

  Alt 28. Jan 2014, 15:44
Zitat:
Delphi-Quellcode:
procedure procedure1();
begin
  Form1.Memo1.Lines.Add('procedure 1 gestartet');
  //irgendwelche dinge
  Form1.Memo1.Lines.Add('procedure 1 beendet');
end;
Was macht denn "irgendwelche dinge"?

Wenn da nichts mit der GUI oder was anderem Globalen gemacht wird, dann solltest du nur die beiden Lines.Add synchronisieren und nicht die ganze Prozedur.
So würde das "irgendwelche dinge" im Thread laufen und nicht die GUI blockieren.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Multithreading GUI

  Alt 28. Jan 2014, 16:00
Im Anhang das komplette Projekt und hier nur das Formular. Das ist nix mit massiv paralleler Verarbeitung der Jobs, sondern ein Thread kümmert sich um die Verarbeitung der übergebenen Jobs.

Inklusive der Rückmeldung an das Formular.
Delphi-Quellcode:
unit FormMain;

interface

uses
  ThreadedJobQueue, ProcJob,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TMainForm = class( TForm )
    Button1 : TButton;
    CheckBox1 : TCheckBox;
    CheckBox2 : TCheckBox;
    CheckBox3 : TCheckBox;
    ListBox1 : TListBox;
    procedure Button1Click( Sender : TObject );
  private
    FJobQueue : TThreadedJobQueue;
    procedure LogStr( const AStr : string );
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

var
  MainForm : TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.AfterConstruction;
begin
  inherited;
  FJobQueue := TThreadedJobQueue.Create;
end;

procedure TMainForm.BeforeDestruction;
begin
  inherited;
  FJobQueue.Free;
end;

procedure TMainForm.Button1Click( Sender : TObject );
begin
  if FJobQueue.IsWorking then
  begin
    LogStr( 'Nicht hektisch werden :o)' );
    Exit;
  end;

  if CheckBox1.Checked then
    FJobQueue.AddJob( TProcJob.Construct(
          procedure
      begin
        LogStr( 'Start 1' );
        Sleep( 1000 );
        LogStr( 'Ende 1' );
      end ) );

  if CheckBox2.Checked then
    FJobQueue.AddJob( TProcJob.Construct(
      procedure
      begin
        LogStr( 'Start 2' );
        Sleep( 1000 );
        LogStr( 'Ende 2' );
      end ) );

  if CheckBox3.Checked then
    FJobQueue.AddJob( TProcJob.Construct(
      procedure
      begin
        LogStr( 'Start 3' );
        Sleep( 1000 );
        LogStr( 'Ende 3' );
      end ) );

  FJobQueue.ProcessJobs;
end;

procedure TMainForm.LogStr( const AStr : string );
begin

  // Diese Methode achtet von selber darauf,
  // dass der eigentlich Zugriff im MainThread-Context erfolgt

  if MainThreadID = GetCurrentThreadId then
  begin

    ListBox1.ItemIndex := ListBox1.Items.Add( AStr );

  end
  else
    TThread.Queue( nil,
      procedure
      begin
        LogStr( AStr );
      end );
end;

end.
Angehängte Dateien
Dateityp: zip dp_178798.zip (2,9 KB, 45x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
value is NULL

Registriert seit: 10. Sep 2010
249 Beiträge
 
#8

AW: Multithreading GUI

  Alt 29. Jan 2014, 08:39
ich versuche das mal umzusetzen und zu verstehen!

danke auf jeden Fall!
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.351 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Multithreading GUI

  Alt 28. Jan 2014, 15:12
Ein schönes Tutorial zu Threads gibt es von Luckie:
http://www.michael-puff.de/Programmi...phi/Tutorials/

Ich spiele auch gerade mit Threads und GUI (aber nicht VCL und FMX) herum.
Man darf grundsätzlich nicht schreibend aus zwei Threads auf einen Speicherplatz zugreifen.

Entweder kann man undefinierte Ergebnisse erhalten oder direkt Zugriffsfehler.
Das kann man sich gut an einer Liste verdeutlichen.
Wenn ein Thread gerade einen neuen Eintrag anhängen will und ein anderer zum gleichen Zeitpunkt den ersten Eintrag entfernt wird das zu einem Fehler führen.

Das selbe Problem besteht bei Zugriffen auf die GUI-Controls.
Um diese Probleme zu vermeiden gibt es CriticalSections. Thread1 "sperrt den Speicherplatz oder eine Komponente" bis er fertig ist mit seiner Aufgabe. Solange muss Thread2 warten und kann seine Aufgabe erst danach erledigen.

Syncronisize kapselt intern eine CriticalSection und vereinfacht so deren Verwendung (geht aber nur bei der Syncronisierung mit dem Mainthread).

Bei langen Berechnungen muss man überlegen, wie oft man Syncronisize aufruft, da das den Berechnungsthread bremst (er muss warten bis der Mainthread fertig ist). In Bezug auf die VCL oder FMX wäre ich nicht sicher, ob sich dabei alle Probleme vermeiden lassen.


Warum verwendest Du überhaupt Threads? Soll der Anwender zwischendurch weiter arbeiten können? Nur dann machen Threads wirklich Sinn.
Andernfalls könntest Du Deine Schalter deaktivieren und in Deinen Funktionen gelegentlich Application.Processmessages aufrufen.
Dann würde man die Einträge im Memo sehen und das Formular optisch noch etwas tun.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  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 22:34 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz