![]() |
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 |
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. |
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 ;)
|
Re: thread
|
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 ;)
|
Re: thread
Zitat:
...:cat:... |
Re: thread
sorry dann bin ich da wohl zu doof, diese 3 paintboxen verwirren mich da irgendwie ...
|
Re: thread
Hier mal ein einfacher Thread Code:
Delphi-Quellcode:
Wenn du das Sleep im Hauptthread ausführst, dann bleibt deine Benutzeroberfläche stehen, aber im Thread ist das getrennt ;)
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; |
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
|
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 |
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);
|
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:
genommen, in den 3 sekunden sleep reagiert das programm allerdings trotzdem nicht
procedure TThreadSortForm.BubbleSortBoxPaint(Sender: TObject);
begin showmessage('test'); sleep(3000); showmessage('ausgeschlafen'); //PaintArray(BubbleSortBox, BubbleSortArray); end; 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 |
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 .... |
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 |
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. |
Re: thread
Hallo,
für diese Routinen musst Du die Unit "SysUtils" einbinden. Gruß xaromz |
Re: thread
vielen dank, darauf muß man erstmal kommen
|
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:
was habe ich denn jetzt schon wieder falsch gemacht ?
// 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; |
Re: thread
Zitat:
Kann es jetzt aus dem Kopf nicht genau sagen, ich glaube, es war StrUtils. Die OH wird Dir da sicher weiterhelfen. Gruß onlinekater |
Re: thread
mm was anmelden ?
habe die selben units drinn (und mehr) wie im demoprogramm was hier gepostet wurde
Delphi-Quellcode:
zu StrUtils findet die OH leider nichts, und ansonsten weiß ich ja nicht wonach ich suchen muß
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, idURI, IdMultipartFormData, IdTCPClient, IdHTTP, StdCtrls, Grids, ComCtrls; |
Re: thread
völlig klar das dein Programm hängt und zwar deswegen:
Delphi-Quellcode:
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.
procedure Thread_Nr_02.Execute;
begin while not Terminated do begin Synchronize(Hauptprogramm); end; end; 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. |
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; |
Re: thread
Nein, jegliche Änderungen an VCL-Controls müssen in einem Synchronize-Kontext, also im Hauptthread, durchgeführt werden.
|
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