![]() |
TThread Execute Methode dauerhaft laufen lassen
Hi,
gibt es eine Möglichkeit, dass die Methode Execute der erbenden TThread-Klasse, wie wenn man mit WinAPI einen Thread erstellt und ihn dauerhaft mit einer While-Schleife laufen lässt, dauerhaft laufen zu lassen? Der Grund ist, ich möchte eine Winsock-Klasse erstellen und muss dort dauerhaft die Funktion recv() aufrufen lassen. MfG: sk0r |
Re: TThread Execute Methode dauerhaft laufen lassen
Du hast die Lösung doch schon selber genannt. Ja das geht.
|
Re: TThread Execute Methode dauerhaft laufen lassen
Delphi-Quellcode:
MfG
while true do begin
// code recv(s, buffer, sizeof(buffer)); // code end; |
Re: TThread Execute Methode dauerhaft laufen lassen
Du weißt aber, dass die Sockets von Windows auch andere Möglichkeiten anbieten, als das ständige Polling. --> WSAAsyncSelect
|
Re: TThread Execute Methode dauerhaft laufen lassen
Hi,
wenn du einen Thread in einer Schleife laufen lassen willst, nimm am besten eine Bedingung mit Terminated, also repeat ... until Terminated oder so. Falls du ihn dann doch Beenden möchtest, geht es dann ganz einfach über TThread.Terminate. So lange du das nicht aufrufst, wird dein Thread weiterlaufen (Vorausgesetzt es gibt keine unbehandelten Exceptions, kein break und kein exit in deinem Code). Mfg FAlter |
Re: TThread Execute Methode dauerhaft laufen lassen
Naja, das Problem ist, wenn ich
Delphi-Quellcode:
benutze, dann wird meine Hauptanwendung blockiert. :/
procedure Thread.Execute;
begin while true do begin //Irgendwas machen Sleep(10); end; end;
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; thread = class(TThread) procedure Execute; end; var Form1: TForm1; gthread: thread; implementation {$R *.dfm} procedure thread.Execute; begin while true do begin ShowMEssage('TEST'); Sleep(10); end; end; procedure TForm1.FormCreate(Sender: TObject); begin gthread := thread.Create(true); end; procedure TForm1.Button1Click(Sender: TObject); begin gthread.Execute; end; end. |
Re: TThread Execute Methode dauerhaft laufen lassen
Hi,
du darfst nicht direkt die Execute aufrufen. Stattdessen musst du den Thread mit Resume starten (oder du übergibst gleich false an den Thread, dann wird er sofort gestartet). Und ich glaube, ShowMessage aus dem Thread aufzurufen fällt in die Kategorie, in welcher Synchronize angesagt ist. Nimm lieber eine MessageBox. Mfg FAlter |
Re: TThread Execute Methode dauerhaft laufen lassen
ein "override" wäre in der Deklaration der Methode execute noch sehr hilfreich.
|
Re: TThread Execute Methode dauerhaft laufen lassen
Ok, bei Resume bekomme ich nun einen abstrakten Error. ó_Ò
Kann jemand mal meinen Code ansehen? Wäre echt nett.
Delphi-Quellcode:
unit sockettest;
interface uses SysUtils, Classes, Windows, Winsock; type TSockThread = class(TThread) iSock: Cardinal; recvProc: procedure(szString: String); procedure Execute; end; TSmallSock = class constructor Create(Address: PChar; Port: Cardinal); procedure Free; private lpAddress: PChar; dwPort: Cardinal; iSock: Cardinal; WSAData: TWSAData; addrIn: TSockAddrIn; dwThreadID: Cardinal; gThread: TSockThread; public procRecv: procedure(szString: String); function DoConnect:Boolean; function SendString(szString: String):Boolean; end; var gSmallSock: TSmallSock; implementation procedure TSockThread.Execute; var mBuf: array[0..1000-1] of Char; begin if recv(gSmallSock.iSock, mBuf, sizeof(mBuf), 0) <> SOCKET_ERROR then begin if mBuf <> '' then begin recvProc(mBuf); mBuf := ''; end; end; end; constructor TSmallSock.Create(Address: PChar; Port: Cardinal); begin lpAddress := Address; dwPort := Port; end; function TSmallSock.DoConnect:Boolean; begin result := false; try if WSAStartup(MAKEWORD(2, 2), WSAData) <> SOCKET_ERROR then begin iSock := socket(AF_INET, SOCK_STREAM, 0); if iSock = SOCKET_ERROR then exit; addrIn.sin_family := AF_INET; addrIn.sin_port := htons(dwPort); addrIn.sin_addr.S_addr := inet_addr(lpAddress); if connect(iSock, addrIn, sizeof(addrIn)) <> SOCKET_ERROR then begin gThread := TSockThread.Create(true); gThread.iSock := iSock; gThread.recvProc := procRecv; gThread.Resume; result := true; end; end; except WSACleanup; end; end; function TSmallSock.SendString(szString: String):Boolean; begin result := false; if send(iSock, szString, length(szString), 0) <> SOCKET_ERROR then result := true; end; procedure TSmallSock.Free; begin inherited Free; gThread.DoTerminate; WSACleanup; end; end. |
Re: TThread Execute Methode dauerhaft laufen lassen
Zitat:
|
Re: TThread Execute Methode dauerhaft laufen lassen
Hi,
Die Lösung steht hier: Zitat:
FAlter [edit] Mal wieder kein roter Kasten. :P Sonst habe wenigstens ich immer Glück. [/edit] |
Re: TThread Execute Methode dauerhaft laufen lassen
Ok, danke für eure Hilfe. Hab ich wohl eine Sache der Grundkenntnisse vergessen. :/
|
Re: TThread Execute Methode dauerhaft laufen lassen
... und deine Procedure "Free" kannst du auch gleich mal in die Tonne drücken und als
Delphi-Quellcode:
gleich mal neu auferstehen lassen...
Destructor Destroy; override;
|
Re: TThread Execute Methode dauerhaft laufen lassen
Hier:
![]() |
Re: TThread Execute Methode dauerhaft laufen lassen
Noch etwas:
Du greifst in deinem Thread auf eine globale Variable zu (gSmallSock.iSock). Du hast doch dein Sockethandle bereits innerhalb deines Threadobjektes. Das kannst du doch benutzen. Die Procedure "recvProc" muss Threadsafe sein oder du musst vorher synchronisieren. |
Re: TThread Execute Methode dauerhaft laufen lassen
Darf ich fragen, was Du mit Threadsafe genau meinst?^^
|
Re: TThread Execute Methode dauerhaft laufen lassen
Du darfst in einer Funktion/Unit/Klasse/etc. , die du ThreadSafe haben möchtest, niemals auf Variablen oder Speicher zugreifen, die auch ausserhalb dieses Objektes genutzt werden (oder du musst synchronisieren).
Für dich bedeutet dass, dass du in RecvProc nur lokale Variablen verwenden darfst und vor allem keine GUI. |
Re: TThread Execute Methode dauerhaft laufen lassen
Und wie kann ich es machen, damit ich auf globale Variablen/Speicher zugreifen darf, ohne Fehler zu verursachen?
Weil, irgendwie muss es ja gehen, die TClientSocket Komponente arbeitet doch auch mit Threads!? |
Re: TThread Execute Methode dauerhaft laufen lassen
Delphi-Quellcode:
type
TSockThread = class(TThread) iSock: Cardinal; recvProc: procedure(szString: String); procedure Execute; override; protected FBuffer:string; procedure CallRecvProc; end; TSmallSock = class constructor Create(Address: PChar; Port: Cardinal); procedure Free; private lpAddress: PChar; dwPort: Cardinal; iSock: Cardinal; WSAData: TWSAData; addrIn: TSockAddrIn; dwThreadID: Cardinal; gThread: TSockThread; public procRecv: procedure(szString: String); function DoConnect:Boolean; function SendString(szString: String):Boolean; end; var gSmallSock: TSmallSock; implementation procedure TSockThread.CallRecvProc; begin recvProc(FBuffer); end; procedure TSockThread.Execute; var mBuf: array[0..1000-1] of Char; begin if recv(iSock, mBuf, sizeof(mBuf), 0) <> SOCKET_ERROR then begin if mBuf <> '' then begin FBuffer:=mBuf; synchronize(CallRecvProc); mBuf := ''; end; end; end; |
Re: TThread Execute Methode dauerhaft laufen lassen
Ok, eine Frage habe ich noch. :/
Wenn ich TClientSocket benutze und es kommen Daten rein, dann bleibt das Programm "hängen", bis TClientSocket.OnRecieve ausgeführt wurde. Wie kann ich das realisieren? Weil im Moment wird es ja "gleichzeitig" ausgeführt. Ich hoffe, ihr wisst, was ich meine. :/ |
Re: TThread Execute Methode dauerhaft laufen lassen
Nö, ich verstehe nicht, was du meinst.
Ist Tclientsocket jetzt von dir , oder meinst du die Komponente von Delphi? Und die willst du jetzt in einen Thread packen? Oder was meinst du mit warten? Edit: Ich würde dir übrigens raten einen neuen Forum-Thread zu erstellen. Dann reagieren meist mehr Leute und ausserdem ist es für das gesamte Forum besser, wegen der Suche. (Kannst ja einen Link zu diesme Thread setzen) |
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