Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi thread (https://www.delphipraxis.net/74332-thread.html)

Nisbo 1. Aug 2006 15:07


thread
 
Moin Moin,

irgendwie komme ich mit den threads nicht so recht klar, habe da schon einiges gelesen aber so nen richtiges zu verstehendes beispiel habe ich da nicht gefunden :(

Bin leider mehr der Bsp-Typ, also Code lesen und verstehen
nach thread zu suchen ist eine qual, bei google und auch hier deswegen mal eine bitte an euch

könnte jemand mal einen ganz einfachen code mit zwei threads erstellen, also wenn man auf Button 1 clickt dann soll
showmessage('T1'); erscheinen und bei button 2 dann showmessage('T2');
also den kompletten code der unit hier posten ?

hoffe das ich das ganze dann besser verstehe

PS: habe D5 Standard

Die Muhkuh 1. Aug 2006 15:09

Re: thread
 
ähm, das mit Threads zu machen, ergibt keinen sinn.

Threads sind z.B. für rechenintensive Aufgaben da, damit die Mainform nicht einfriert.

Nisbo 1. Aug 2006 15:12

Re: thread
 
ja das ist schon klar, ich wollte ja nur ein einfaches übersichtliches Beispiel haben, selber nutzen möchte ich das wenn ich dateien aus dem internet runterlade denn da hängt das programm sonst, den cod emit showmessage tausche ich dann halt einfach aus ;)

TBx 1. Aug 2006 15:18

Re: thread
 
guckst mal hier :-D

hoffe, das hilft Dir weiter

onlinekater

Nisbo 1. Aug 2006 15:23

Re: thread
 
mal schauen ob ich aus der demo schlau werde, da ist mir eigendlich schon wieder zuviel code drinn, deswegen auch meine frage wegen den 2 buttons und showmessage, eventuell erbarmt sich ja noch einer ;)

sakura 1. Aug 2006 15:41

Re: thread
 
Zitat:

Zitat von Nisbo
mal schauen ob ich aus der demo schlau werde, da ist mir eigendlich schon wieder zuviel code drinn, deswegen auch meine frage wegen den 2 buttons und showmessage, eventuell erbarmt sich ja noch einer ;)

Einfacher geht es kaum. Zwei Buttons sind schon einer mehr als in der einfachen Demo von Borland ;)

...:cat:...

Nisbo 1. Aug 2006 15:44

Re: thread
 
sorry dann bin ich da wohl zu doof, diese 3 paintboxen verwirren mich da irgendwie ...

jfheins 1. Aug 2006 15:54

Re: thread
 
Hier mal ein einfacher Thread Code:
Delphi-Quellcode:
type
  TMyThread: class (TThread)
    Status: String;

    procedure Execute; override;
    procedure VCL_Result;
  end;


procedure TMyThread.Execute;
begin
  Status := 'fange an';
  synchronize (VCL_Result);

  // Der Threadcode
  Sleep(2000);

  Status := 'fertig';
  synchronize (VCL_Result);
end;

procedure VCL_Result,
begin
Form1.Label1.Caption := Status;
end;
Wenn du das Sleep im Hauptthread ausführst, dann bleibt deine Benutzeroberfläche stehen, aber im Thread ist das getrennt ;)

Nisbo 1. Aug 2006 15:58

Re: thread
 
hallo und erstmal danke für die antwort, aber das sind auch wieder solche kurzen ausschnitte die keine komplette übersicht sind und noobs wie mir nicht wirklich helfen, weswegen ich ja auch nach den beiden buttons und den gesamten code der unit gefragt hatte

hoika 1. Aug 2006 16:07

Re: thread
 
Hallo,

dein Bsp mit den 2 Buttons ist halt für
Threads ungeeignet.
Threads werden meistens benutzt,
um ohne Nutzereinfluss mehrere Arbeiten gleichzeitig
zu machen.

Was willst du denn konkret machen ?

Heiko

Sascha L 1. Aug 2006 16:15

Re: thread
 
Wieso? Er hat erstens gesagt, was er machen möchte und er hat auch gesagt, dass das mit den Buttons nur ein Beispiel sein soll, damit er es versteht!

@Nisbo:

Füge eine neue Unit zu deinem Projekt hinzu. Da kopierste dann den Code von jfheins rein.

OnButton1Click:

Delphi-Quellcode:
MyThreadVar := TMyThread.Create(false);

Nisbo 1. Aug 2006 16:16

Re: thread
 
unter anderen das runterladen von csv-dateien sowie das verarbeiten selbiger, das selber geht ja auch (bis auf meine anderen fragen :D) nur ich möchte halt das mein programm dabei nicht einfriert

aus der delphidemo habe ich gesehen das mit den threads ja auch nur andere prozeduren aufgerufen werden nur ist mir dabei zuviel unwichtiges drinn, also allgemein zuviel, bin momentan immernoch dabei den code soweit zu kürzen das nur eine message kommt, das ist aber halt nicht wirklich einfach für einen noob in sachen threads

habe da auch schon mal experimentiert und

Delphi-Quellcode:
procedure TThreadSortForm.BubbleSortBoxPaint(Sender: TObject);
begin
showmessage('test');
sleep(3000);
showmessage('ausgeschlafen');
  //PaintArray(BubbleSortBox, BubbleSortArray);
end;
genommen, in den 3 sekunden sleep reagiert das programm allerdings trotzdem nicht

wie gesagt ob jetzt ne showmessage sinnvoll ist oder nicht sei mal dahingestellt, mir geht es in der hinsicht um das verstehen durch das ansehen von code

man könnte ja auch in der einen prozedur bei button 1 eine zahl solange um 1 erhöhen bis 1 Billion erreicht ist und das dann in einem tedit ausgeben, allerdings muß button 2 dann irghendwas anderes machen könen wie z.b. showmessage ausgeben ohne das das programm hängt

Nisbo 1. Aug 2006 16:20

Re: thread
 
@ Sascha L

ist doch auch wieder nur ein schnipsel und dazu dann noch über 2 units verteilt :(
wo einfügen ? das sind dann alles so fragen die mir durch den kopf gehen weswegen ich ja nach einem kompletten code frage

ich denke ich trinke erstmal nen bier, mir dampft der kopf ....

xaromz 1. Aug 2006 16:25

Re: thread
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich habe Dir mal ein kommentiertes Testprojekt mit einem Button erstellt.
Schau Dir das mal an und stell dann konkrete Fragen.

Der Thread im Beispielprogramm lässt einfach eine Progressbar laufen, damit man ihn arbeiten sieht.

Anzumerken wäre noch, dass das nur ein Beispiel ist und man Thread keinesfalls in der hier gezeigten Weise verwenden sollte. Beispielsweise sollte man einen Thread nicht jedesmal neu erstellen, sondern lieber jedesmal aufwecken, wenn es etwas zu tun gibt.

Gruß
xaromz

Nisbo 1. Aug 2006 17:51

Re: thread
 
@ xaromz

vielen dank, jetzt komme ich langsam vorwärts, habe deinen code auch schon etwas verändert und erweitert sowie einen neuen thread erstellt, jetzt stellt sich aber die frage warum eine standardfunktion wie strtoint oder inttostr nicht funktioniert, bekomme da nur undefinierter bezeichner

so schaut dein kompletter umgebauter democode jetzt aus

Delphi-Quellcode:
unit Unit1;

interface

uses
  Forms, StdCtrls, Classes, Controls, ComCtrls;

type
  TForm1 = class(TForm)
    ProgressBar1: TProgressBar;
    Button1: TButton;
    ProgressBar2: TProgressBar;
    Button2: TButton;
    Edit1: TEdit;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses
  Windows, Dialogs;

{$R *.dfm}

{ TMyThread }

// Thread 1 START Thread 1 START Thread 1 START Thread 1 START
// Thread 1 START Thread 1 START Thread 1 START Thread 1 START
// Thread 1 START Thread 1 START Thread 1 START Thread 1 START
// Thread 1 START Thread 1 START Thread 1 START Thread 1 START
type
  Thread_Nr_01 = class(TThread)
    PB: TProgressBar;
    procedure Hauptprogramm;
    procedure Execute; override;
  end;

procedure Thread_Nr_01.Execute;
begin
  while not Terminated do begin
    Synchronize(Hauptprogramm); // Zugriff auf VCL-Elemente synchronisieren
    Sleep(10);                 // etwas warten VCLSync
  end;
end;

procedure Thread_Nr_01.Hauptprogramm;
var zahlenwert : integer;
begin
  // Fertig?
  if PB.Position < PB.Max then PB.StepIt // Progressbar weiter
  else Terminate;                       // Thread beenden
end;

// Button 1 Click
procedure TForm1.Button1Click(Sender: TObject);
var Th: Thread_Nr_01;
begin
  ProgressBar1.Position := 0;     // ProgressBar 1 auf Null setzen
  Th := Thread_Nr_01.Create(True); // Thread erzeugen (suspended)
  Th.FreeOnTerminate := True;     // Thread gibt sich selbst frei
  Th.PB := ProgressBar1;          // Progressbar 1 zuweisen
  Th.Resume;                      // Thread starten
  ShowMessage('Thread für PB1');  // Message anzeigen, Thread läuft weiter
end;

// Button 2 Click
procedure TForm1.Button2Click(Sender: TObject);
var Th: Thread_Nr_01;
begin
  ProgressBar2.Position := 0;     // ProgressBar 2 auf Null setzen
  Th := Thread_Nr_01.Create(True); // Thread erzeugen (suspended)
  Th.FreeOnTerminate := True;     // Thread gibt sich selbst frei
  Th.PB := ProgressBar2;          // Progressbar 2 zuweisen
  Th.Resume;                      // Thread starten
  ShowMessage('Thread für PB2');  // Message anzeigen, Thread läuft weiter
end;

// Thread 2 START Thread 2 START Thread 2 START Thread 2 START
// Thread 2 START Thread 2 START Thread 2 START Thread 2 START
// Thread 2 START Thread 2 START Thread 2 START Thread 2 START
// Thread 2 START Thread 2 START Thread 2 START Thread 2 START
type
  Thread_Nr_02 = class(TThread)
    procedure Hauptprogramm;
    procedure Execute; override;
  end;

procedure Thread_Nr_02.Execute;
begin
  while not Terminated do begin
    Synchronize(Hauptprogramm); // Zugriff auf VCL-Elemente synchronisieren
    Sleep(10);                 // etwas warten VCLSync
  end;
end;

procedure Thread_Nr_02.Hauptprogramm;
var zahlenwert : integer;
begin
  zahlenwert := 0;
  zahlenwert := StrToInt(Form1.Edit1.Text);
  if zahlenwert < 10 then begin
    Form1.Edit1.Text := intotostr(zahlenwert + 1);
    //Form1.Edit1.Text := '1';
  end;

  Terminate;                       // Thread beenden
end;

// Button 3 Click
procedure TForm1.Button3Click(Sender: TObject);
var Th: Thread_Nr_02;
begin
  Th := Thread_Nr_02.Create(True); // Thread erzeugen (suspended)
  Th.FreeOnTerminate := True;     // Thread gibt sich selbst frei
  Th.Resume;                      // Thread starten
end;

end.

xaromz 1. Aug 2006 18:31

Re: thread
 
Hallo,

für diese Routinen musst Du die Unit "SysUtils" einbinden.

Gruß
xaromz

Nisbo 1. Aug 2006 18:37

Re: thread
 
vielen dank, darauf muß man erstmal kommen

Nisbo 1. Aug 2006 19:27

Re: thread
 
ok habe das ganze jetzt in mein hauptprogramm eingebaut und der aufruf klappt auch, allerdings hängt das programm immer noch als ob es keinen thread geben würde

hier der teil vom programm incl dem threadbereich

Delphi-Quellcode:
// Thread 2 START Thread 2 START Thread 2 START Thread 2 START
type
  Thread_Nr_02 = class(TThread)
    procedure Hauptprogramm;
    procedure Execute; override;
  end;

procedure Thread_Nr_02.Execute;
begin
  while not Terminated do begin
    Synchronize(Hauptprogramm);
  end;
end;

procedure Thread_Nr_02.Hauptprogramm;
var
  data: TIdMultiPartFormDataStream;
  dieurl : string;
  A: TStrArray;
  AnzTokens, i, ccc, ccc2: Integer;
  csv: TStringList;
begin
  Screen.Cursor := crHourGlass;
  data := TIdMultiPartFormDataStream.Create;
  dieurl := Form1.Edit1.Text;
  try
    data.AddFormField('id', '1');
    Form1.Memo1.Text := Form1.IdHTTP1.Post(dieurl, data);
    Form1.Memo1.Lines.SaveToFile('shops.txt');
  finally
    data.Free;
  end;

  ccc := -1;
  if FileExists('shops.txt') then begin
    csv := TStringList.Create;
    csv.LoadFromFile('shops.txt');
    Form1.StringGrid1.Rowcount := csv.Count;

    for ccc2 := csv.Count - 1 downto 1 do begin
      AnzTokens := Explode(A, ';', csv.Strings[ccc2]);
      for i := 0 to AnzTokens -1 do begin
        ccc := ccc + 1;
        if ccc < 6 then begin Form1.StringGrid1.Cells[ccc, ccc2] := A[i]; end;
        if ccc = 6 then begin ccc := -1; end;
      end;
    end;
  end;
  Screen.Cursor := crDefault;
  Terminate;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Th: Thread_Nr_02;
begin
  Th := Thread_Nr_02.Create(True); // Thread erzeugen (suspended)
  Th.FreeOnTerminate := True;     // Thread gibt sich selbst frei
  Th.Resume;                      // Thread starten
end;
was habe ich denn jetzt schon wieder falsch gemacht ?

TBx 1. Aug 2006 19:34

Re: thread
 
Zitat:

Zitat von Nisbo
jetzt stellt sich aber die frage warum eine standardfunktion wie strtoint oder inttostr nicht funktioniert, bekomme da nur undefinierter bezeichner

na, weil Du wohl die entsprechende Unit nicht angemeldet hast.

Kann es jetzt aus dem Kopf nicht genau sagen, ich glaube, es war StrUtils. Die OH wird Dir da sicher weiterhelfen.

Gruß

onlinekater

Nisbo 1. Aug 2006 19:39

Re: thread
 
mm was anmelden ?

habe die selben units drinn (und mehr) wie im demoprogramm was hier gepostet wurde

Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  IdBaseComponent, IdComponent, IdTCPConnection, idURI, IdMultipartFormData,
  IdTCPClient, IdHTTP,
  StdCtrls, Grids, ComCtrls;
zu StrUtils findet die OH leider nichts, und ansonsten weiß ich ja nicht wonach ich suchen muß

SirThornberry 1. Aug 2006 19:42

Re: thread
 
völlig klar das dein Programm hängt und zwar deswegen:
Delphi-Quellcode:
procedure Thread_Nr_02.Execute;
begin
  while not Terminated do begin
    Synchronize(Hauptprogramm);
  end;
end;
du syncronisierst ja durchweg (mit syncronize) den Thread mit dem Hauptprogramm-Thread. Und wenn es syncron zum Hauptprogramm läuft hängt das Hauptprogramm wenn der Thread hängt und umgekehrt.

Stell dir die Threads einfach mal als 2 Läufer vor. Normalerweise können beide unabhäng von einander Ihre strecke rennen und wenn einer eine Pause macht kann der andere trotzdem weiterlaufen. Mit Syncronize sorgst du allerdings dafür dass die Läufer sich die Hände reischen. Somit kann keiner mehr davon laufen und selbständig laufen weil er vom anderen festgehalten wird. Dadurch das du syncronize in einer Schleife hast halten sich die Läufer also immer wieder gegenseitig fest. Syncronize macht also nur sinn wenn der eine Läufer dem anderen was geben soll. Ansonsten sollten die beide Läufer möglichst nie Händchenhaltend rennen.

Oder anderes Beispiel: Du willst ein Stück Kuchen und eine Tube Haargel. Damit das schnell geht schickst du einen deiner Freunde zum Fleischer und den anderne ins Kaufland. Würde du beide zusammenketten (syncronize) würden die beiden Freunde die ganze Zeit miteinander quatschen und bräuchten länger als einer alleine. Deshalb sollte man die Freunde nie zusammenketten außer es ist unbedingt notwendig.


Wenn du mal wieder so einen Fehler wie "undefinierter Bezeichner" hast guck am besten als erstes in die Hilfe. Da steht in aller Regel bei funktionen dabei in welcher Unit sich diese befinden.

Nisbo 1. Aug 2006 20:06

Re: thread
 
ok das mit den läufern ist einleuchtend, aber wie laufen die jetzt richtig ?

ist das so korrekt ? weil so gehts zumindest

Delphi-Quellcode:
procedure Thread_Nr_02.Execute;
begin
  while not Terminated do begin
    Hauptprogramm
  end;
end;

Khabarakh 1. Aug 2006 20:15

Re: thread
 
Nein, jegliche Änderungen an VCL-Controls müssen in einem Synchronize-Kontext, also im Hauptthread, durchgeführt werden.

SirThornberry 1. Aug 2006 20:15

Re: thread
 
In deiner Funktion "Hauptprogramm" änderst du den Inhalt des Memos. Dieses Memo wird allerdings auf der grafischen Oberfläche des Hauptthreads dargestellt. Wenn du also aus deinem Thread die Funktion "Hauptprogramm" aufrufst machst du dinge im Hauptthread obwohl du ja eigentlich einen eigenen Thread genommen hast um dich von diesem zu lösen. Du solltest generell davon abstand nehmen in einem Thread auf das Haupprogramm zu zugreifen. Wenn du unbedingt auf das Hauptprogramm zugreifen musst, dann muss dies mit Syncronize passieren sonst kann es passieren das der Hauptthread und dein eigener Thread gleichzeitig auf etwas zugreifen und dann passieren lustige Effekte und nix geht mehr. Du müsstest dein Programm also umschreiben da du die Berechnungen alle im Thread machst und NUR ausgaben mit Syncronize im Hauptthread machst. Daher wurde am Anfang des Themas auch geschrieben das Threads nur sinn machen wenn du intensive Berechnungen hast (wo also nicht ständig auf den Hauptthread mit Ausgaben etc. zugegriffen wird). In deinem Beispiel solltest du auch ohne Thread auskommen und dafür mit "Application.ProcessMessages" dafür sorgen das die Anwendung nicht ganz einfriert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02: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-2025 by Thomas Breitkreuz