AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread Terminate

Ein Thema von schweindi · begonnen am 14. Mär 2010 · letzter Beitrag vom 14. Mär 2010
Antwort Antwort
Seite 1 von 2  1 2      
schweindi

Registriert seit: 4. Feb 2010
60 Beiträge
 
#1

Thread Terminate

  Alt 14. Mär 2010, 14:31
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:
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;
Und im Form1 (Heuptfenster) wird per Buttonklick das gemacht:

Delphi-Quellcode:
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;
Wenn die procedure Stop Aufgerufen wird, dann ändert sie zwar Stopped = True aber die Schleife merkt das garnicht!
Ich dachte "Application.ProcessMessages;" sollte das lösen....

lg
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.007 Beiträge
 
Delphi 12 Athens
 
#2

Re: Thread Terminate

  Alt 14. Mär 2010, 14:34
Ich vermisse den Code für die Execute Methode!
Uwe Raabe
  Mit Zitat antworten Zitat
schweindi

Registriert seit: 4. Feb 2010
60 Beiträge
 
#3

Re: Thread Terminate

  Alt 14. Mär 2010, 14:55
ahja:
Delphi-Quellcode:
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;
so das ist dann alles
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.007 Beiträge
 
Delphi 12 Athens
 
#4

Re: Thread Terminate

  Alt 14. Mär 2010, 15:09
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
Uwe Raabe
  Mit Zitat antworten Zitat
schweindi

Registriert seit: 4. Feb 2010
60 Beiträge
 
#5

Re: Thread Terminate

  Alt 14. Mär 2010, 15:26
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.007 Beiträge
 
Delphi 12 Athens
 
#6

Re: Thread Terminate

  Alt 14. Mär 2010, 15:41
Zitat von schweindi:
1) die Memo Sachen habe ich nur eingebaut, damit ich sehe, was überhaupt gesendet/ empfangen wird
Ist aber nunmal verboten, da die VCL nicht threadsicher ist.

Zitat von schweindi:
2) Die Schleife wird sofort erreicht, doch sie wird erst bei einem Inputchar (eben RXCHAR) beendet.
Du bekommst aber innerhalb der Schleife keinen neuen Wert für signaled - da fehlt einfach etwas.

Zitat von schweindi:
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.
Das ist auch OK.

Zitat von schweindi:
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.
Ja, aber der Wert von Signaled ändert sich nicht innerhalb der Schleife.

Zitat von schweindi:
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.
Schon, aber der Aufruf von Input wird nicht durch Stopped verhindert und da rufst du DoThread wieder auf und der Zirkus geht weiter.
Uwe Raabe
  Mit Zitat antworten Zitat
HERMES

Registriert seit: 29. Nov 2004
142 Beiträge
 
#7

Re: Thread Terminate

  Alt 14. Mär 2010, 16:15
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.007 Beiträge
 
Delphi 12 Athens
 
#8

Re: Thread Terminate

  Alt 14. Mär 2010, 16:19
Zitat von HERMES:
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.
Soweit hatte ich noch gar nicht gelesen, aber das geht natürlich so wirklich nicht.
Uwe Raabe
  Mit Zitat antworten Zitat
schweindi

Registriert seit: 4. Feb 2010
60 Beiträge
 
#9

Re: Thread Terminate

  Alt 14. Mär 2010, 16:51
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?
  Mit Zitat antworten Zitat
HERMES

Registriert seit: 29. Nov 2004
142 Beiträge
 
#10

Re: Thread Terminate

  Alt 14. Mär 2010, 17:50
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:
var
 InputMon:T...Thread;
weg
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz