![]() |
Thread Terminate
hallo,
ich versuche gerade einen Thread "auszuschalten" und habe schon eigentlich alles ausprobiert (Destroy, Free, Suspend, Terminate) leider kam jedes Mal ein "Access Denied" Fehler. Jetzt bin ich draufgekommen, wieso. Das ist mein Thread, den ich schließen will, und die Pfeile markieren die Schleife, die das Problem darstellt:
Delphi-Quellcode:
Und im Form1 (Heuptfenster) wird per Buttonklick das gemacht:
type
TMonThread = class(TThread) private procedure Input; protected procedure Execute; override; public Stopped : Boolean; constructor Create; destructor Destroy; override; procedure DoThread(Status : Boolean); procedure Stop; end; {...} procedure TMonThread.DoThread(status : Boolean); var Overlapped: TOverlapped; Signaled : DWORD; begin Signaled:=0; if ComPort2.InstanceActive then SetCommMask(ComPort2.Handle, EV_RXCHAR) else begin Form1.Memo_sms.Lines.Add('SetCommMask not set'); exit; end; //set waiting mask FillChar(Overlapped, SizeOf(Overlapped), 0); Overlapped.hEvent := CreateEvent(nil, True, True, nil); WaitCommEvent(ComPort2.Handle, Signaled , @Overlapped); repeat //<-------------------------------------- sleep(readint); Form1.Memo_sms.Lines.Add(IntToStr(Signaled)); Application.ProcessMessages; until (Signaled = EV_RXCHAR) or (Stopped = True); //<---------- if (Signaled = EV_RXCHAR) then begin Form1.Memo_sms.Lines.Add('Input!'); Input; end; end; {...} procedure TMonThread.Stop; begin Form1.Memo_sms.Lines.Add('Thread Destroyed'); // clear buffers SetCommMask(ComPort2.Handle, 0); PurgeComm(ComPort2.Handle, PURGE_TXCLEAR or PURGE_RXCLEAR); //stop thread Stopped:= True; end; destructor TMonThread.Destroy; begin inherited Destroy; end;
Delphi-Quellcode:
Wenn die procedure Stop Aufgerufen wird, dann ändert sie zwar Stopped = True aber die Schleife merkt das garnicht!
procedure TForm1.s_B_disconnectClick(Sender: TObject);
var InputThread : TMonThread; begin //stop Thread & destroy InputThread.Stop; //<--------------------------------- //purge buffers of port if ComPort2.InstanceActive then begin ComPort2.Flush; ComPort2.CloseSocket; end; Ich dachte "Application.ProcessMessages;" sollte das lösen.... lg |
Re: Thread Terminate
Ich vermisse den Code für die Execute Methode!
|
Re: Thread Terminate
ahja:
Delphi-Quellcode:
so das ist dann alles :)
procedure TMonThread.Execute;
begin DoThread(False); end; procedure TMonThread.Stop; begin Form1.Memo_sms.Lines.Add('Thread Destroyed'); // clear buffers SetCommMask(ComPort2.Handle, 0); PurgeComm(ComPort2.Handle, PURGE_TXCLEAR or PURGE_RXCLEAR); //stop thread Stopped:= True; end; procedure TMonThread.Input; var input,Answer : String; begin Input := ComPort2.RecvTerminated(readtotal,eol); ShowMessage('" '+Input+' "'); DoThread(False); end; |
Re: Thread Terminate
1. Ausser im Hauptthread sollten keine VCL-Aufrufe erfolgen (z.B. die Memo-Adds)
2. Application.ProcessMessages gehört (wenn überhaupt) in den HauptThread. Eigentlich solltest du ganz darauf verzichten. 3. Deine repeat-Schleife wird erst erreicht, wenn ein etwas empfangen wird. Den wiederholten Aufruf von DoThread hast du in der Methode Input versteckt, die immer dann aufgerufen wird, wenn ein Zeichen empfangen wurde - auch wenn Stopped = true ist! Folge: - solange nichts empfangen wird, erfolgt auch keine Abfrage von stopped - obwohl stopped = true, wird weiter auf Input gewartet - das ganze beendet sich nur bei einem anderen CommEvent als EV_RXCHAR |
Re: Thread Terminate
1) die Memo Sachen habe ich nur eingebaut, damit ich sehe, was überhaupt gesendet/ empfangen wird :)
2) Die Schleife wird sofort erreicht, doch sie wird erst bei einem Inputchar (eben RXCHAR) beendet. Deshalb wollte ich eben, als zweite Bedingung (Stopped = True) einsetzen, damit ich, wenn ich zb die Verbindung zum Com Port unterbreche den Thread anhalten kann. 3) Wenn ich das Programm ausführe wird die Memo mit "Signaled : DWORD" gefüllt, eben jedes Mal kommt eine 0, da kein Char empfangen wurde - dh die Schleife wird ausgeführt. Es soll ja nach der Procedure Stop nicht mehr auf Input gewartet werden (also schleife soll nicht mehr ausgeführt werden). Und das dachte ich kann ich mir der Abbruchbedingung "until (Signaled = EV_RXCHAR) or (Stopped = True);" erreichen. |
Re: Thread Terminate
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Thread Terminate
Wenn du in deinem Formular mit diesem code arbeitest, dann wird in deiner s_B_disconnectClick Methode ein anderes TMonThread Objekt verwendet als in den anderen Methoden, somit hat der aufruf von Stop keine Auswirkung auf dein anderes Thread Objekt, das irgendwo anderst erzeugt und gestartet wurde.
|
Re: Thread Terminate
Zitat:
|
Re: Thread Terminate
okay...
1) ich habe es gerade nochmal ausprobiert: Wenn die Schleife läuft ist natürlich Signaled auf 0 dann gebe ich im Hyperterm irgendwas ein dann ist die Schleife Fertig (Signaled = EV_RXCHAR) und dann ruft er input auf. Also das "WaitCommEvent(ComPort2.Handle, Signaled, @overlapped);" ändert sofort Signaled, da es Input gibt. 2) Memos sind draußen 3) wie kann ich per Buttonklick genau dem Thread sagen, er soll zb Suspended werden? |
Re: Thread Terminate
Du musst die Threadvariable als Klassenmember deiner Formularklasse deklarieren und alle Deklarationen als lokale Variable entfernen.
Edit: warscheinlich hast du InputThread in deiner Klasse deklariert, also lasse einfach das
Delphi-Quellcode:
weg
var
InputMon:T...Thread; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:24 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