AGB  ·  Datenschutz  ·  Impressum  







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

Thread pausieren lassen und aufwecken

Ein Thema von Quo · begonnen am 18. Feb 2008 · letzter Beitrag vom 20. Feb 2008
Antwort Antwort
Seite 1 von 2  1 2      
Quo

Registriert seit: 18. Feb 2008
6 Beiträge
 
#1

Thread pausieren lassen und aufwecken

  Alt 18. Feb 2008, 23:28
Hi Leute, helft mir bitte ...

folgendes, ich habe eine unendliche schleife in ein thread eingebaut,
diese schleife prüft eine Variable (hier checkbox1.checked:=true) wenn dise variable true ist, wird in meinem Tread eine Procedure aus eienem anderen Unit gestartet, bevor diese Pocedure startet, wird mein Thread pausiert (Thred.suspend).

Nun, wenn die Procedure durchgelaufen ist (checkbox1.checked:=false), will ich das mein Tread weiter läuft und das soll von alleine geschehen (ohne das ich irgendwas mache).

Danke!!!
Delphi-Quellcode:
unit Tread;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type TAnzeigeTread=class(TThread)
Sender: TObject;
constructor create(CreateSuspended : boolean); virtual;
protected
procedure execute; override;
procedure Doetwas;virtual; abstract;
{ Public-Deklarationen } 
end;

TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Button2: TButton;
Button4: TButton;
Edit3: TEdit;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure etwas(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private

public
{ Public-Deklarationen } 
AnzeigeTread:TAnzeigetread;
end;
var
Form1: TForm1;
i:integer;
a:string;
b:boolean;
implementation

uses Unit2;



{$R *.dfm} 
constructor TAnzeigeTread.create(CreateSuspended : boolean);
begin
FreeOnTerminate := True;
inherited Create(CreateSuspended);


end;

procedure TAnzeigeTread.Execute;

begin
i:=0;
while(not Terminated)do
begin
if form1.CheckBox1.Checked then
form2.Button1Click(sender);
if b=true then

form1.Edit1.Text:=a;

Form1.etwas(Sender);
sleep(50);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
b:=true;
AnzeigeTread:= TAnzeigeTread.create(true);
AnzeigeTread.Resume;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
AnzeigeTread.Suspend;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
AnzeigeTread.resume;
end;


procedure TForm1.etwas(Sender:TObject);

begin
i:=i+1;
a:=inttostr(i)+'mda';

end;


procedure TForm1.Button3Click(Sender: TObject);
begin
b:=false;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
form2.show;
end;

end.
........

Delphi-Quellcode:
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,tread;

type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen } 
public
{ Public-Deklarationen } 
end;

var
Form2: TForm2;
AnzeigeTread:TAnzeigetread;
implementation



{$R *.dfm} 

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.AnzeigeTread.Suspend;

Form1.Edit3.Text:= 'ok';
Sleep(1000);
form1.CheckBox1.Checked:=false;
Form1.AnzeigeTread.Resume; // Wie kann ich mein thread weiterfortsetzen????
Form1.Edit3.Text:= 'weiter';
end;

end.
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 01:15
Ein paar Fragen zu deinem Code:

1. Warum definierst du den Constructor deines Threads als virtuell?
2. Warum setzt du FreeOnTerminate vor dem Inherited Aufruf im Constructor?
3. Warum deklarierst du eine virtual abstrakte Methode, wenn es keine Ableitung von dem Thread gibt?
4. Wieso greifst du unsynchronisiert auf die Form und deren Komponenten zu?
5. Warum verwendest du die globale Form1 Variable anstatt z.B. eine richtige Instanz dem Thread zu übergeben?
6. Wozu deklarierst du ein Sender: TObject in deinem Thread?
7. Warum benutzt du globale Variablen in dem Thread?
8. Warum vergleichst du eine boolsche Variable auf explizit auf true?
9. Warum legst du den Thread suspended an um ihn dann sofort loslaufen zu lassen?
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 07:52
Die Win32-API-Übersetzung von 'Ich leg mich schlafen und Du weckst mich auf, wenn was los ist' heißt
WaitForSingleObject bzw. WaitForMultipleObject sowie 'Event' oder 'Semaphore'.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 09:06
Zitat von Muetze1:
2. Warum setzt du FreeOnTerminate vor dem Inherited Aufruf im Constructor?
Weil es durchaus sinnvoll ist bei TThread die Felder vorher zu setzen/initialisieren. Der Thread wird ja bereits bei inherited create gestartet (je nach Parameter), und ab da sollte man keine unsynchronisierten Schreibzugriffe mehr durchführen.

Aber ansonsten muss in diesem Thread noch kräftig aufgeräumt werden.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 09:35
Man kann nicht erwarten, das Einstellungen, die vor einem "Inherited-Create"-Aufruf durchgeführt werden, anschließend noch so vorhanden sind, denn schließlich initialisiert der Create-Aufruf ja alle Eigenschaften. Lieber so:
Delphi-Quellcode:
Constructor TMyThread.Create;
Begin
  Inherited Create (True); // Der Thread schläft
  MyData.Initialize; // eigene Felder, Daten etc. initialisieren
  Resume; // und dann, zum Schluß der Initialisierung aufwecken
End;
So ist es imho auch sauberer.
)
Wenn man möchte, das ein Thread nur dann etwas macht, wenn z.B. eine Checkbox 'gecheckt' ( ) wuirde, dann sollte man im Click-Ereignis der Checkbox den Thread steuern. Ob man das über ein Suspend / Resume, oder mit Hilfe von Synchronisationsobjekten macht, bleibt jedem Selbst überlassen, wobei nur mit den Synch-Objekten gewährleistet ist, das der Thread an einer wohldefinierten Stelle einschläft / aufwacht.

Meine Threads sehen eigentlich immer gleich aus (in der Execute-Methode wird gewartet, das etwas passiert).

Vielleicht kannst Du dein Problem mit Hilfe eines Thread-Pools lösen. Dann musst Du nur die Arbeit definieren (Job), die im Hintergrund ausgeführt wird und über die Synchronisationsmechanismen brauchst Du dir keine Gedanken zu machen. Andererseits dürfte der Code für Dich sehr hilfreich sein.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 10:54
Das mit dem Initialisieren ist ja ein schöner Grund. Aber dies gilt nicht für eigene Felder und auch nicht für TThread (Freeonterminate). Wäre ja auch doof, wenn der Constructor von TThread freeonterminate erst ändert/setzt und dann gleich den Thread startet.
Für den Allgemneingebrauch und wenn man sich keine Gedanken (darüber) beim programmieren machen möchte ist der inherited Aufruf am Anfang der beste Weg. Aber dazu gibt es auch Ausnahmen. Andernfalls hätte man ja die Aufrufreihenfolge des Constructors gleich anders gestalten können.
[Edit]
Ich sehe grade, dass der Thread eh erst nach dem Constructor gestartet wird (in Afterconstruction). Dann nehme ich alle Aussagen zurück. Dann brauch man allerdings auch nicht inherited mit Createsuspended=true aufrufen und man sollte (trotz dass es in den Demos anders ist) das inherited an den Anfang setzen.
[/Edit]


Abgesehen von dem, war das einfach eine Antwort auf muetzes Frage, da sich sonst jeder Anfänger (und auch der Threadersteller) fragen wird, warum es Borland denn anders macht (inherited call ans Ende des Constructors).
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Quo

Registriert seit: 18. Feb 2008
6 Beiträge
 
#7

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 17:10
Zitat von Muetze1:
Ein paar Fragen zu deinem Code:

1. Warum definierst du den Constructor deines Threads als virtuell?
2. Warum setzt du FreeOnTerminate vor dem Inherited Aufruf im Constructor?
3. Warum deklarierst du eine virtual abstrakte Methode, wenn es keine Ableitung von dem Thread gibt?
4. Wieso greifst du unsynchronisiert auf die Form und deren Komponenten zu?
5. Warum verwendest du die globale Form1 Variable anstatt z.B. eine richtige Instanz dem Thread zu übergeben?
6. Wozu deklarierst du ein Sender: TObject in deinem Thread?
7. Warum benutzt du globale Variablen in dem Thread?
8. Warum vergleichst du eine boolsche Variable auf explizit auf true?
9. Warum legst du den Thread suspended an um ihn dann sofort loslaufen zu lassen?

Das Beispiel, was ich hier reingepostet habe, war eigentlich ein testprogramm,
ich versuchte an einem einfacheren Beispiel zu verstehen, wie das ganze funktioniert.
Aber nach eueren Antworten sehe ich, dass die sache mit der Checkbox ein totales blödsinn von mir war.


In wirklichkeit geht es um ein gerät, das mittels serielle schnittstelle mit meinem programm verbundet ist. An das gerät sende ich in einer unendlichen schleife ein Kommando, was sein Status abfrägt und ein Kommando , was die messdaten am display anfordert.
Dieser Schleife ist in einem TTread verkapselt. Das gerät hat zwei Status-Modi...
Wenn ich Status-1 abfange, will ich aus der schleife raus, etwas machen, z.B andere Kommandos an gerät senden und von ihm daten empfangen. Wenn diese Porcedure fertig ist, will ich dass die Schleife die Status abfrägt, weiter läuft.

Wozu das ganze..so kann ich z.B Tasten-Drück am gerät abfangen und gleichzeitig aktuelle Display -Werte in meinem porgramm zu sehen bekommen.

ich habe das ganze bis jetzt ohne suspend ....mit einer StopVariable von typ boolean erledigt

es läuft aber irgendwie unsicher...manchmal wenn ich auf dem Form StopTaste oder StartTaste klicke
springt der Fokus sofort auf die andere TAste dann wieder zurück...

Was ich wollte, dass procedure TMyThreads.Execute sich von alleine schlafen legt und wenn der Code in proceduren
Form1.StartTasteClick(Sender) und Form1.StopTasteClick(Sender) bis zur Ende durgelaufen ist..dann weiter läuft.

Delphi-Quellcode:
procedure TMyThreads.Execute;
var

  Label 10,20,30;
begin

Form1.Edit11.Text:='Ende';

while(not Terminated)do

begin

10:Application.ProcessMessages;

 If StopVariable=true then
  begin
    CP.RTS(1);
    CP.SENDSTRING('sta,g'+chr(13)+chr(10));
    status:=cp.READSTRING();
  
    If trim(Status)='E 01then goto 10;
    If trim(Status)='then goto 10;
    Form1.Edit6.Text:='begin';
    Sleep(100);

   
    If (trim(Status)='04') and (StopJa=true) then
        begin
          Form1.StopTasteClick(Sender);

        end;

      If (trim(Status)='00') and (StopJa=true) then
          begin
          Form1.StopTasteClick(Sender);

          end;

    If (trim(Status)='02')and (StartJa=true) then
            begin
       
                Form1.StartTasteClick(Sender);
            end;
   /// Die letzten aktuellen Messwerten bekommen

20: CP.SENDSTRING('dis,g'+chr(13)+chr(10));

    Distanz:=cp.READSTRING();
    Distanz:=trim(Distanz);
If (length(Distanz)<11) or (length(Distanz)>11) then goto 20;

    Sleep(50);

    Test:='okkkkkkkkkkkkkk';

30: CP.SENDSTRING('kmh,g'+chr(13)+chr(10));
    Speed:=cp.READSTRING();
    Speed:=trim(Speed);
 If (length(Speed)<3) and (length(Speed)>5) then goto 30;


    Form1.Edit6.Text:='untennnnnnnnnnn';

    ///*
   
      end ;
    Synchronize(Go);

    end;

end;
  Mit Zitat antworten Zitat
Quo

Registriert seit: 18. Feb 2008
6 Beiträge
 
#8

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 17:40
Vielen Dank für Ihre Thread Klasse, werde mir unbedingt runterladen und versuchen zu verstehen.

Leider in meinem programm brauche ich keinen code, welcher in Hintergrund was "heimlich" macht.)

Sonder es geht, um das sicheren Freisetzen der serielle Schnittstelle...

ich will das die Prozedur MyThreads.Execute für eine Weile nichts tut .


Haben sie vielleicht ein leichverständliches beispiel für WaitForSingleObject???

Kann man vielleicht so machen...das die

Prozedur MyThreads.Execute auf eine Variable wartet oder auf die Beendigung der "Stoptaste-Procedure"??
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 18:37
Das wäre jetzt ein Beispiel für Event und waitforsingleobject. Allerdings habe ich nicht direkt die API-Funktionen benutzt, sondern eine Klasse, die genau diese Funktionen kapselt/benutzt.

Der Thread würde von Button1 gestartet. aber er läuft erst weiter, wenn Button2 gedrückt wurde.
Delphi-Quellcode:
uses ...,syncobjs;

type TmyThread=class(TThread)
     public
     protected
       procedure execute; override;
     end;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    event:TEvent;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TmyThread.execute;
var event:TEvent;
begin
  event:=TEvent.Create(nil,true,false,'myEvent'); //Zugriff aus dasselbe Event
  event.waitfor(infinite);

  //mach etwas


  event.free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var thread:TmyThread;
begin
  label1.Caption:='warte';

  event:=TEvent.Create(nil,true,false,'myEvent'); //Event anlegen (mit Namen)

  with Tmythread.Create(true) do //Thread starten
  begin
    FreeOnTerminate:=true;
    resume;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  event.SetEvent;
  event.Free;
end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Quo

Registriert seit: 18. Feb 2008
6 Beiträge
 
#10

Re: Thread pausieren lassen und aufwecken

  Alt 19. Feb 2008, 19:01
uf...Danke werde in ein paar stunden ausprobieren
  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 22:11 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