AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

TThread und Rückgabe an Formular

Ein Thema von tofse · begonnen am 19. Jun 2014 · letzter Beitrag vom 19. Jun 2014
Antwort Antwort
Seite 1 von 2  1 2   
tofse

Registriert seit: 6. Jun 2011
Ort: Saarlouis
131 Beiträge
 
Delphi XE Professional
 
#1

TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 08:52
Hallo,
ich beschäftige mich gerade mit TThread, das funktioniert bisher ganz gut, nur frage ich mich, wie ich am besten eine Kommunikation mit dem Formular hinbekomme.
Im Thread werden Dateien kopiert. Im Hauptformular soll ein Fortschrittsbalken angezeigt werden und der Dateiname, der gerade kopiert wird.

Mit synchronize funktioniert das ja, aber in verschiedenen Tutorials habe ich gelesen, dass man das nicht machen würde. Das wäre ja pro Schleifendurchlauf im Thread ein Aufruf von synchronize, der jedesmal den Thread kurz unterbrechen würde.
Wie sieht es denn mit eigenen Events aus? Im Internet habe ich dazu gar nichts gefunden. Also das Definieren von einem Event im Thread, z.B. onFileCopied, worauf ich im Hauptformular reagieren würde. Das wäre der Weg gewesen, den ich ohne Nachlesen spontan genommen hätte, aber wie gesagt, da ich dazu gar nichts gefunden habe, weiß ich jetzt auch nicht, ob "man das nicht macht"?

Gruß und schönen Feiertag
Christof
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 09:04
Ei sah mo, hann ihr heid kä Feierdah?

Wenn ein Thread mit VCL Komponenten kommuniziert kommt man meines Wissens nicht um ein Synchronize herum. Was du machen könntest wäre das Evnet z.B. nur 11 mal aufzurufen (0%, 10%, 20%, .. 80%, 90%, 100%).

Gruß aus Dingmatt via Monnem.
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 09:19
Hi!

Natürlich brauchst Du das nicht bei jedem Schleifendurchlauf ein Syncornize zu machen, aber Du kannst auch einfach an Dein Formular ne Message senden.

Mavarik

Delphi-Quellcode:
CONST
  WM_Sync = WM_User + 100;
  SM_MSG = 1; // Ganzen Text
  SM_Prozent = 2; // Nur %

type
  PSyncMSG = ^TSyncMSG;
  TSyncMSG = record
               MSG : String[255];
               PZ : Integer;
             end;

  TMaifForm = Class(TForm)
    private
         procedure MySyncronize(var MSG: TMessage); message WM_Sync;

  end;

procedure TMyThread.Execute;
Var
  MyMessage : PSyncMSG;
  I : Integer;
begin
  // ...
  New(MyMessage);

  MyMessage^.MSG := 'Hey ich bearbeite gerade: "Cool.pdf"';
  MyMessage^.PZ := 7;

  Postmessage(MainForm.Handle,WM_Sync,SM_MSG,LParam(MyMessage));

  for i:=0 to 100 do
    begin
      if I mod 10 = 0 then
        begin
          New(MyMessage);

          MyMessage^.MSG := '';
          MyMessage^.PZ := i;

          Postmessage(MainForm.Handle,WM_Sync,SM_Prozent,LParam(MyMessage));
        end;
    end;
  // ...
end;

procedure TMainform.MySyncronize(var MSG: TMessage);
var
  SyncMSG : PSyncMSG;
begin
  SyncMSG := PSyncMSG(MSG.LParam);

  Case MSG.WParam of
    SM_MSG : begin
                   Label1.Caption := SyncMSG^.MSG;
                   Processbar1.Position := SyncMSG^.PZ;
                 end;
    SM_Prozent : begin
                   Processbar1.Position := SyncMSG^.PZ;
                 end;
  end;

  Dispose(SyncMSG);
end;

Geändert von Mavarik (19. Jun 2014 um 09:39 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#4

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 10:27
Mit synchronize funktioniert das ja, aber in verschiedenen Tutorials habe ich gelesen, dass man das nicht machen würde. Das wäre ja pro Schleifendurchlauf im Thread ein Aufruf von synchronize, der jedesmal den Thread kurz unterbrechen würde.
Neuere Delphi Versionen enthalten die Methode TThread.Queue, die im Unterschied zu Synchronize den Thread nicht sofort blockiert (sondern erst zu einem späteren Zeitpunkt). Queue legt den eigenen Methodenaufruf in eine Warteschlange und gibt die Kontrolle sofort an den Thread zurück. Im Haupthread wird dann "später" diese Queue abgearbeitet. Eine Garantie dafür gibt es aber nicht, z.B. falls beim Beenden des Programms noch Einträge in dieser Queue sind.
Michael Justin
  Mit Zitat antworten Zitat
Mschmidt

Registriert seit: 4. Jul 2010
Ort: Berlin
62 Beiträge
 
Delphi XE2 Professional
 
#5

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 12:53
Ich verwende dazu Methodenaufrufe:

Delphi-Quellcode:
type
  TMainProc = procedure (<Parameter>) of object;

type
  TMain = Class(TForm)
...
  procedure Aktualisiere(<Parameter>);
...
  procedure StartThread;
end;

Type
  TMeinThread = Class(TThread)
  fMainProc :TMainProc;
  procedure Execute;
  constructor Create(MainProc:TMainProc);
end;

Constructor TMeinThread.Create;
begin
  ...
  fMainProc:= MainProc;
...
end;

procedure TMeinThread.Execute;
begin
  while not terminated do begin
  if (<Zähler>) and (assigned(fMainProc)) then
    synchronize ( begin fMainProc(<Parameter>)end;); // anonyme Methode
  ...
end;

procedure TMain.StartThread;
begin
  TMeinThread.create(Aktualisiere);
  ...
end;

procedure TMain.Aktualisiere(<Parameter>);
begin
  // dieser code wird aus dem Thread aufgerufen
...
end;
grüsse Mschmidt
  Mit Zitat antworten Zitat
tofse

Registriert seit: 6. Jun 2011
Ort: Saarlouis
131 Beiträge
 
Delphi XE Professional
 
#6

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 16:46
Hallo,

vielen Dank für die vielen Tipps.
Zu meiner Frage bzgl. Events hat sich noch niemand geäußert.
Ich habe es mal so versucht:

TCopyErrorEvent = procedure(Sender: TObject;Datei:String;Fehler:String) of Object; Das hat funktioniert.
Nur wie gesagt, im Netz habe ich zu dieser Möglichkeit, Rückmeldung ans Formular zu geben, gar nichts gefunden. Deshalb: macht man das nicht, aus irgendeinen Grund, wie Performance oder hängt der Thread dann auch kurz?

Danke
  Mit Zitat antworten Zitat
Mschmidt

Registriert seit: 4. Jul 2010
Ort: Berlin
62 Beiträge
 
Delphi XE2 Professional
 
#7

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 16:51
Selbstverständlich macht man das, ansonsten wäre ja die methode synchronize obsolet,oder?
Dem thread ist das letztendlich egal. Das gibt auch keine Fehler oder sonst was, es sei den, du baust falsch....
Cheers mschmidt
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 17:12
Events so wie du sie verwendest, dürfen vom Thread nur mit Synchronize aufgerufen werden.
Synchronize bedeuted, der Thread muss Anhalten, wenn der Hauptthread mal nichts zu tun hat führt er das Event aus, danach wird der Thread wieder aufgeweckt.

Der Vorschlag mit Postmessage ist da deutlich besser.
  Mit Zitat antworten Zitat
tofse

Registriert seit: 6. Jun 2011
Ort: Saarlouis
131 Beiträge
 
Delphi XE Professional
 
#9

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 17:23
Ah, ok, habs verstanden.

Danke
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: TThread und Rückgabe an Formular

  Alt 19. Jun 2014, 17:30
Events so wie du sie verwendest, dürfen vom Thread nur mit Synchronize aufgerufen werden.
Synchronize bedeuted, der Thread muss Anhalten, wenn der Hauptthread mal nichts zu tun hat führt er das Event aus, danach wird der Thread wieder aufgeweckt.

Der Vorschlag mit Postmessage ist da deutlich besser.
Nja, der Vergleich hinkt etwas.

Also, grundsätzlich dürfen Zugriffe auf die VCL (Delphi-GUI) nur aus dem Hauptthread erfolgen.
Synchronize nimmt die Funktion und führt sie im Hauptthread aus, wobei das natürlich so lange warten muß, bis der Haupthtead mal Zeit und Lust dafür hat.
Synchronize wartet mit der Ausführung, bis die übergebene Funktion fertig ist und erst dann läuft der Thread weiter.

Queue übergibt das auch an den Hauptthread, genau wie Synchronize, nur kehrt das sofort zurück und lässt den thread weiterarbeiten. Der Hauptthread führt aber auch da die Prozedur erst dann aus, wenn er kann.

Delphi-Referenz durchsuchenTThread.Synchronize -> MSDN-Library durchsuchenSendMessage
Delphi-Referenz durchsuchenTThread.Queue -> MSDN-Library durchsuchenPostMessage

Wenn du also das Synchronize-Equivalent "SendMessage" verwendet hättest, dann würde der Thread ebenfalls warten müssen, bis die Message verarbeitet wurde.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  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 14:50 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