Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Thread freezed - Warum?? (https://www.delphipraxis.net/145730-thread-freezed-warum.html)

Sereby 7. Jan 2010 08:43


Thread freezed - Warum??
 
Hiho,

ich benutze Delphi 2009 U3 auf Win7 x64 RTM.
Folgendes Zenario:
1. ich habe einen Work-Thread erstellt um die GUI zugänglich zu lassen während das Programm arbeitet.
2. Habe ich die Verschiedenen Aufgaben ebenfalls in eigene Thread in deren eigenen Units gepackt

Das Problem ist dass der Arbeits-Thread auf beendigung der Aufgaben-Threads warten muss und dafür verwende ich Global in der GUI angelegte ThreadVariablen und .waitfor... also z.b. in der GUI steht dann
WorkThread: TWorkThread = nil;
ThreadAufgabe1: TThreadAufgabe1 = nil;
...

und auf diese variablen greif ich im Worker Thread auch zu und erstelle den Thread da drinnen

Delphi-Quellcode:
  if (ThreadAufgabe1 = nil) then
  begin
    ThreadAufgabe1 := TThreadAufgabe1.Create;
    ThreadAufgabe1.OnTerminate := frmGUI.OnAufgabe1ThreadTermination;
    ThreadAufgabe1.Resume;
    ThreadAufgabe1.WaitFor;
  end;
der Thread läuft auch durch und wartet auch.. aber irgendwie kommt der nicht zum ende?! Wenn ich Stoppunkte setze, und versuche mit F9 dahin zu springen, dann freezed der sofort! Wenn ich aber den thread nur mit F7 durchgehe, dann passiert der all meine Stoppunkte und freezed erst beim end; vom Execute part.

Was kann da schief laufen und wie kann ich das rausfinden warum das so ist?
Achja.. in Onterminate kommt er gar nicht erst rein!

DataCool 7. Jan 2010 12:10

Re: Thread freezed - Warum??
 
Hi,

um Dir zu helfen brauchen wir schon etwas Code des Threads.

Eine Frage habe ich aber schon so:

Startest Du den Thread so(s. Source) aus der Hauptanwendung ?
Delphi-Quellcode:
if (ThreadAufgabe1 = nil) then
  begin
    ThreadAufgabe1 := TThreadAufgabe1.Create;
    ThreadAufgabe1.OnTerminate := frmGUI.OnAufgabe1ThreadTermination;
    ThreadAufgabe1.Resume;
    ThreadAufgabe1.WaitFor;
  end;
Wenn ^^das^^ aus der Hauptanwendung gestartet wird, dann wartet der Main-Thread des Programms
bei WaitFor solange bis der Thread fertig ist, d.h. solange ist Deine Anwendung blockiert und
der Sinn eines Threads total verfehlt.

Gruß Data

Sereby 7. Jan 2010 12:30

Re: Thread freezed - Warum??
 
nein das mit waitfor ist im bereits erstellten thread. Der andere verwaltungsthread ist aber auf die selbe art erzeugt worden bloss ohne WaitFor.

etwas mehr debuggen hat zu tage gebracht, dass es an Synchronize liegt?!?!!!!
die delphi ide meint dass der Haupt-Thread durch nen SendMessage aufgehalten wird..
ich rufe in dem erstellten Thread die procedure SetTextOf auf welche ich selbst definiert habe

wenn ich im Thread folgendes aufrufe, dann kommt der nicht bis zum ende!
Delphi-Quellcode:
...
begin
  SetTextOf(FDebugCtrl,'',False,True);
  SetTextOf(FDebugCtrl,'',False,True);
  SetTextOf(FDebugCtrl,'',False,True);
  SetTextOf(FDebugCtrl,'',False,True);
end;
FDebugCtrl wurde im Workerthread an den AufgebenThread übergeben und entspricht GUIApply.DebugText (GUIApply ist ein frame)

Delphi-Quellcode:
procedure TGUIThreadHelper.SetTextOf(Element: TControl; Text: String;
  AddTime, ReplaceText: Boolean; FontStyles: TFontStyles;
  FontSize: Integer; FontColor: TColor);
begin
  FDstCtrl := Element;
  FTmpStr := Text;
  FReplace := ReplaceText;
  FFontStyles := FontStyles;
  FTmpBool := AddTime;
  FTmpInt := FontSize;
  FFontColor := FontColor;
  Synchronize(SetText);
end;

procedure TGUIThreadHelper.SetText;
begin
  if (FDstCtrl = nil) then Exit;
  if (FDstCtrl is TsRichEdit) then
  begin
    if FReplace then
      TsRichEdit(FDstCtrl).Text := FTmpStr
    else
    begin
      if TsRichEdit(FDstCtrl).Hint = 'log' then
      begin
        //TsRichEdit(DstCtrl).SelStart := TsRichEdit(DstCtrl).SelLength; //oben anhängen
        //nach unten jumpen
        TsRichEdit(FDstCtrl).SelStart := Length(TsRichEdit(FDstCtrl).Text); //geschmeidig unten anhängen und gleich hinspringen

        //Zeit absplitten damit nur der rest gestyled wird
        if FTmpBool then
          TsRichEdit(FDstCtrl).SelText := FormatDateTime('hh:mm:ss.zzz', Now) + ' >> ';

        //nach unten jumpen
        TsRichEdit(FDstCtrl).SelStart := Length(TsRichEdit(FDstCtrl).Text); //geschmeidig unten anhängen und gleich hinspringen

        //stylen und hinzufügen
        TsRichEdit(FDstCtrl).SelAttributes.Style := FFontStyles;
        TsRichEdit(FDstCtrl).SelAttributes.Color := FFontColor;
        TsRichEdit(FDstCtrl).SelAttributes.Size := FTmpInt;
        TsRichEdit(FDstCtrl).SelText := FTmpStr;
      end else
        TsRichEdit(FDstCtrl).Text := TsRichEdit(FDstCtrl).Text + FTmpStr;
    end;
    TsRichEdit(FDstCtrl).Refresh;
  end else if (FDstCtrl is TEdit) or (FDstCtrl is TsEdit) then
  begin
    if FReplace then TEdit(FDstCtrl).Text := FTmpStr
    else TEdit(FDstCtrl).Text := TEdit(FDstCtrl).Text + FTmpStr;
    TEdit(FDstCtrl).Font.Style := FFontStyles;
    TEdit(FDstCtrl).Font.Color := FFontColor;
    TEdit(FDstCtrl).Font.Size := FTmpInt;
    TEdit(FDstCtrl).Refresh;
  end else if (FDstCtrl is TButton) or (FDstCtrl is TsButton) then
  begin
    if FReplace then TButton(FDstCtrl).Caption := FTmpStr
    else TButton(FDstCtrl).Caption := TButton(FDstCtrl).Caption + FTmpStr;
    TButton(FDstCtrl).Font.Style := FFontStyles;
    TButton(FDstCtrl).Font.Color := FFontColor;
    TButton(FDstCtrl).Font.Size := FTmpInt;
    TButton(FDstCtrl).Refresh;
  end else if (FDstCtrl is TLabel) or (FDstCtrl is TsLabel) then
  begin
    if FReplace then TLabel(FDstCtrl).Caption := FTmpStr
    else TLabel(FDstCtrl).Caption := TLabel(FDstCtrl).Caption + FTmpStr;
    TLabel(FDstCtrl).Font.Style := FFontStyles;
    TLabel(FDstCtrl).Font.Color := FFontColor;
    TLabel(FDstCtrl).Font.Size := FTmpInt;
    TLabel(FDstCtrl).Refresh;
  end else if (FDstCtrl is TsGauge) then
  begin
    if FReplace then
      TsGauge(FDstCtrl).Hint := FTmpStr
    else
      TsGauge(FDstCtrl).Hint := TsGauge(FDstCtrl).Hint + FTmpStr;
  end else if (FDstCtrl is TComboBox) or (FDstCtrl is TsComboBox) then
  begin
    if FReplace then TComboBox(FDstCtrl).Items.Text := FTmpStr
    else TComboBox(FDstCtrl).Items.Text := TComboBox(FDstCtrl).Items.Text + FTmpStr;
    TComboBox(FDstCtrl).Font.Style := FFontStyles;
    TComboBox(FDstCtrl).Font.Color := FFontColor;
    TComboBox(FDstCtrl).Font.Size := FTmpInt;
    TComboBox(FDstCtrl).Refresh;
  end else if (FDstCtrl is TRadioButton) or (FDstCtrl is TsRadioButton) then
  begin
    if FReplace then TRadioButton(FDstCtrl).Caption := FTmpStr
    else TRadioButton(FDstCtrl).Caption := TRadioButton(FDstCtrl).Caption + FTmpStr;
    TRadioButton(FDstCtrl).Font.Style := FFontStyles;
    TRadioButton(FDstCtrl).Font.Color := FFontColor;
    TRadioButton(FDstCtrl).Font.Size := FTmpInt;
    TRadioButton(FDstCtrl).Refresh;
  end else if (FDstCtrl is TCheckBox) or (FDstCtrl is TsCheckBox) then
  begin
    if FReplace then TCheckBox(FDstCtrl).Caption := FTmpStr
    else TCheckBox(FDstCtrl).Caption := TCheckBox(FDstCtrl).Caption + FTmpStr;
    TCheckBox(FDstCtrl).Font.Style := FFontStyles;
    TCheckBox(FDstCtrl).Font.Color := FFontColor;
    TCheckBox(FDstCtrl).Font.Size := FTmpInt;
    TCheckBox(FDstCtrl).Refresh;
  end;
end;
- TsRichedit ist eine Komponente aus dem AlphaControls Package
- WorkerThread sowie die Aufgaben ist abgeleitet von TGUIThreadHelper und der von TThread

Blup 7. Jan 2010 14:28

Re: Thread freezed - Warum??
 
Wenn alle deine Aufgaben in dieser Form aus dem Arbeitsthread gestartet werden:
Zitat:

Zitat von Sereby
Delphi-Quellcode:
  if (ThreadAufgabe1 = nil) then
  begin
    ThreadAufgabe1 := TThreadAufgabe1.Create;
    ThreadAufgabe1.OnTerminate := frmGUI.OnAufgabe1ThreadTermination;
    ThreadAufgabe1.Resume;
    ThreadAufgabe1.WaitFor;
  end;

Sind für die Aufgaben keine eigenen Threads erforderlich.
Hier würden einfache Objekte genügen.

Zitat:

Zitat von Sereby
etwas mehr debuggen hat zu tage gebracht, dass es an Synchronize liegt?!?!!!!
die delphi ide meint dass der Haupt-Thread durch nen SendMessage aufgehalten wird..

Synchronize(SetText);
Übergibt die Methode SetText and den Hauptthread und wartet so lange, bis dieser Zeit hat, diese zu verarbeiten.
Wenn dieser keine Zeit dafür hat, solltest du mal nachschaun, was er den eigentlich zur Zeit macht.

Sereby 7. Jan 2010 18:59

Re: Thread freezed - Warum??
 
ok problem ist gelöst.. habe an einer stelle bevor ich den Sub-thread erstelle dooferweise ne funktion aufgerufen bei der ich noch auf gui elemente direkt zugegriffen habe! Deswegen hat er gefreezed.

Jetzt habe ich allerdings ein anderes Problem:
Zitat:

Exception-Klasse EThread mit Meldung 'Thread-Fehler: Das Handle ist
ungültig (6)'.
Dafür hab ich auch nen Demo-Code :)

SirThornberry 7. Jan 2010 19:24

Re: Thread freezed - Warum??
 
ohne deinen Quelltext gelesen zu haben vermute ich das du vom Thread aus auf ein VCL-Object zugreifst.

Sereby 7. Jan 2010 20:47

Re: Thread freezed - Warum??
 
ok auch das problem habe ich nun lösen können:
hab das FreeOnTerminate bei Execute verworfen und das ganze so und es funzt wie gewüscht

Delphi-Quellcode:
      AufgabenThread := TAufgabenThread.Create;
      AufgabenThread.FreeOnTerminate := False;
      AufgabenThread.Resume;
      AufgabenThread.WaitFor;
      FreeAndNil(AufgabenThread);


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:56 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