![]() |
Thread execute wird nicht ausgeführt
Halli Hallo,
Ich möchte einen Clienten schreiben der Dauerhaft versucht auf einen Server zu connecten und dann evtl. auch was hinzuschicken. Um Das Programm damit nicht langsamer zu amchen habe ich diesen Teil in einen Thread gepackt. Weil ich mit Threads noch kine Erfahrungen gemacht habe habeich ein neues Programm erstellt um das ganze übersichtlich zu haben und es besser zu verstehen. Nun Wird aber Execute im Thread garnicht ausgeführt. Könnt ihr mir vielleicht sagen wo mein Fehler steckt? Main-Unit:
Delphi-Quellcode:
Thread-Unit:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Unit2, ExtCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient; type TForm1 = class(TForm) Button1: TButton; IdTCPClient1: TIdTCPClient; procedure FormCreate(Sender: TObject); private Main : TMain; public Time:string; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin Main := TMain.Create(tpnormal); end; end.
Delphi-Quellcode:
also das Synchronize wird schon garnicht mehr ausgeführt...
unit Unit2;
interface uses Classes, ExtCtrls, WinSock, SysUtils, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient; type TMain = class(TThread) IdTCPClient: TIdTCPClient; Timer1: TTimer; private protected procedure Execute; override; procedure Update; public constructor Create(ThreadPriority: TThreadPriority); end; implementation uses Unit1; { Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen nur in einer Methode namens Synchronize aufgerufen werden, z.B. Synchronize(UpdateCaption); und UpdateCaption könnte folgendermaßen aussehen: procedure Main.UpdateCaption; begin Form1.Caption := 'Aktualisiert in einem Thread'; end; } { Main } constructor TMain.Create(ThreadPriority: TThreadPriority); Begin inherited Create(false); Priority:=ThreadPriority; end; procedure TMain.Execute; begin Timer1.Create(nil); IdTCPClient.Create(nil); with IdTCPClient do Begin ASCIIFilter:=false; MaxLineLength:=16384; ReadTimeOut:=0; RecvBufferSize:=32768; SendBufferSize:=32768; end; with Timer1 do Begin enabled:=true; Interval:=1000; end; try IdTCPClient.Connect(100); except end; Synchronize(Update); end; procedure TMain.Update; begin Form1.caption := '00:00:00'; end; end. Ich bin den Quellcode auch schon mit F7 durchgegangen aber ohne Fehler... Danke für jede Antwort |
Re: Thread execute wird nicht ausgeführt
Objekte erzeugst du mit Objekt := TKlasse.Create, nicht mit Objekt.Create. Des weiteren wird zumindest der Timer im Thread nicht so ohne Weiteres funktionieren, da er auf eine Nachrichtenschleife angewiesen ist. Zuguterletzt möchte ich noch vor dem leeren Except-Block warnen; wenn du schon nichts tust, beschränke dich mit der on-Klausel auf bestimmte Exceptions, denn EOutOfMemory oder EStackOverflow kannst du nun mal nicht geeignet behandeln.
|
Re: Thread execute wird nicht ausgeführt
Zitat:
|
Re: Thread execute wird nicht ausgeführt
Okay danke erstmal,
klar: Objekt := TKlasse.Create :wall: ich habe dort (nil) angegeben weil ich nicht wusste welcher Komponennte er sich nun eigentlich unterordnen soll... was könnte ich denn da nehmen? mit dem leeren Except-Block was könnte man da denn reinmachen dass er nix tut xD |
Re: Thread execute wird nicht ausgeführt
@Muetze1: TTimer erzeugt sich doch keinen eigenen Thread. Er setzt auf der SetTimer-API auf, die wiederum Fensternachrichten verwendet.
@Lord_stelzer: Das mit dem nil ist durchaus in Ordnung; du musst nur daran denken, die Objekte in deinem Destruktor oder anderswo wieder freizugeben. Beim Except-Block solltest du dich einfach auf bestimmte Exceptions beschränken - dazu gibt es die "on ExceptionKlasse do"-Klausel. |
Re: Thread execute wird nicht ausgeführt
es geht weiter xD
habs erstmal geschafft, hat alles funktioniert nun kriege ich ne Zugriffsverletzung im Thread-Code Ich bin den Code wieder mit F7 durchgegangen so finde ich meistens meine Fehler aber mit den Threads will das nicht... da meldet er beim Thread.Create den Fehler
Delphi-Quellcode:
unit Unit2;
interface uses Classes, ExtCtrls, WinSock, SysUtils, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient; type TMain = class(TThread) IdTCPClient: TIdTCPClient; Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private protected procedure Execute; override; procedure Update; public hour1, min1, sek1, sekunden1, stime:real; Port, time1:integer; Host, S, nTime:string; constructor Create(ThreadPriority: TThreadPriority); end; implementation uses Unit1; { Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen nur in einer Methode namens Synchronize aufgerufen werden, z.B. Synchronize(UpdateCaption); und UpdateCaption könnte folgendermaßen aussehen: procedure Main.UpdateCaption; begin Form1.Caption := 'Aktualisiert in einem Thread'; end; } { Main } function SecondsToTime(wSeconds: Word): TDateTime; var wHours, wMin: Word; begin wHours := Trunc(wSeconds div 3600); wSeconds := wSeconds - (3600 * Trunc(wSeconds div 3600)); wMin := Trunc(wSeconds div 60); wSeconds := wSeconds - (60 * Trunc(wSeconds div 60)); Result := EncodeTime(wHours, wMin, wSeconds, 0); end; constructor TMain.Create(ThreadPriority: TThreadPriority); Begin inherited Create(false); Priority:=ThreadPriority; end; procedure TMain.Execute; begin Timer1 := TTimer.Create(nil); {IdTCPClient:=TIdTCPClient.Create(nil); with IdTCPClient do Begin ASCIIFilter:=false; MaxLineLength:=16384; ReadTimeOut:=0; RecvBufferSize:=32768; SendBufferSize:=32768; end;} with Timer1 do Begin Interval:=1000; enabled:=true; end; Synchronize(Update); end; procedure TMain.Timer1Timer(Sender: TObject); Begin S := FormatDateTime('hh:nn:ss', Time); hour1:=strtoint(copy(S, 1, 2)); min1:=strtoint(copy(S, 4, 2)); sek1:=strtoint(copy(S, 7, 2)); sekunden1:=hour1*3600+min1*60+sek1; time1:=Trunc(sekunden1-sTime); nTime:=timetostr(secondstotime(time1)); { try IdTCPClient.Connect(100); except end; } End; procedure TMain.Update; begin Form1.caption := nTime; end; end. |
Re: Thread execute wird nicht ausgeführt
Zitat:
|
Re: Thread execute wird nicht ausgeführt
Und wer soll die Nachrichten für das Fenster bearbeiten? Das kann nur der Thread tun, der das Fenster erstellt hat. Und er braucht dazu eine Nachrichtenschleife.
|
Re: Thread execute wird nicht ausgeführt
jetzt bekriegt euch hier nicht xD
kann mir lieber einer sagen wie ich sowas mache? (Nachrichtenschleife) |
Re: Thread execute wird nicht ausgeführt
Eine Nachrichtenschleife sieht in der einfachsten Form so aus:
Delphi-Quellcode:
Die müsstest du dann einbauen, wenn der Timer laufen soll. Beenden kannst du die Nachrichtenschleife mit PostQuitMessage(0). Meine hellseherischen Fähigkeiten sagen mir allerdings, dass ein TTimer nicht die beste Lösung für dein Problem ist - jetzt müsste ich nur noch das Problem kennen. :P Wofür willst du den Timer verwenden?
var msg: tagMSG;
while GetMessage(msg, 0, 0, 0) do DispatchMessage(msg); |
Re: Thread execute wird nicht ausgeführt
joa sowas denk ich mir auch mittlerweile...
Ich will mit der Indy Komponennte TIdTCPClient Daten an einen Dazugehörigen Server schicken, allerdings ist dieser Server nicht immer an... und weil er weiterhin versuchen soll zu connecten (falls der Server wieder an geht) zieht das ganz schön Leistung und das Programm hängt... ich schreibe das Programm für einen Kumpel der ein Internetcafé betreibt nun möchte ich nach möglichkeit Rechnung der Preise und Zeit auch mit im Thread unterbringen... |
Re: Thread execute wird nicht ausgeführt
Zitat:
Delphi-Quellcode:
Was soll somit das ganze mit dem Thread zu tun haben? Ein Thread hat nicht automatisch eine Nachrichtenschleife geschweige denn ein Fensterhandle um etwas zu empfangen. Statt dessen musst du die WndProc beim anlegen des Fensters angeben, was - wie nun schon oft genug geäussert - vom TTimer geschieht. Was soll nun also der Thread damit zu schaffen haben?
constructor TTimer.Create(AOwner: TComponent);
begin inherited Create(AOwner); [...] FWindowHandle := Classes.AllocateHWnd(WndProc); [...] end; procedure TTimer.WndProc(var Msg: TMessage); begin with Msg do if Msg = WM_TIMER then try Timer; except Application.HandleException(Self); end else Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam); end; Ich diskutiere hier nicht um den Sinn bzw. Unsinn eines TTimers in einem Thread, da man das in einem Thread besser handhaben kann (WaitMultipleObjects(), etc) sondern nur gegen deine Pauschale Aussage das TTimer hier nicht nutzbar ist, da kein Fenster zur Verfügung steht für selbigen. Und das ist immernoch eine in meinen Augen falsche Aussage deinerseits. Also entweder überzeugst du dich selbst oder du stellst die nächste Behauptung in den Raum, warum das nicht funktionieren sollte ohne Fenster... |
Re: Thread execute wird nicht ausgeführt
Wo habe ich gesagt, dass der Thread ein eigenes Fenster braucht? Er braucht eine Nachrichtenschleife. Wer soll denn sonst auch die WndProc aufrufen? Danke übrigens für die Quellcode-Ausschnitte - ich bin schließlich nicht im entferntesten auf die Idee gekommen, mir die mal anzuschauen, bevor ich meine "Behauptungen" aufgestellt habe.
|
Re: Thread execute wird nicht ausgeführt
es hat übrigens mit dem Timer auch so funktioniert ;) mein Fehler lag im Main-Quelltext dass ich einer Variable im Thread einen Wert geben wollte bevor ich den Tread aufrufe xD
Ich habe nun allerdings ne schleife eingebaut und das Programm auch schon fertig es funktioniert genau so wie es soll ;) Für die die nach der schleife suchen so wie ich vorhin nochmal der code:
Delphi-Quellcode:
procedure TMain.Execute;
begin while not Terminated do Begin S := FormatDateTime('hh:nn:ss', Time); hour1:=strtoint(copy(S, 1, 2)); min1:=strtoint(copy(S, 4, 2)); sek1:=strtoint(copy(S, 7, 2)); sekunden1:=hour1*3600+min1*60+sek1; time1:=Trunc(sekunden1-sTime); nTime:=timetostr(secondstotime(time1)); synchronize(Update); sleep(1000); IdTCPClient.Host := GetIp(Host); IdTCPClient.Port := Port; try IdTCPClient.Connect(100); IdTCPClient.WriteLn(floattostr(time1)); status := IdTCPClient.ReadLn('', 5); Form1.Label9.Caption:='Online'; IdTCPClient.Disconnect; except Form1.Label9.Caption:='Offline'; end; if status='shutdown' then WindowsExit(EWX_POWEROFF or EWX_FORCE); end; end; |
Re: Thread execute wird nicht ausgeführt
Zitat:
|
Re: Thread execute wird nicht ausgeführt
Wie kann ein Fenster eine Nachrichtenschleife haben? Ein Fenster hat eine Fensterprozedur, und mit seiner Nachrichtenschleife ermöglicht ein Thread Windows, die Fensterprozeduren seiner Fenster aufzurufen. Der Hauptthread hat seine Nachrichtenschleife verteilt in den drei Methoden TApplication.Run/HandleMessage/ProcessMessage. Da aber der neu erstellte Thread Application.Run nicht aufruft, muss er anderweitig eine Nachrichtenschleife betreten.
|
Re: Thread execute wird nicht ausgeführt
Du hast Recht.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:21 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