AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi [solved]Thread terminated nicht, obwohl OnTerminate

[solved]Thread terminated nicht, obwohl OnTerminate

Ein Thema von silver-moon-2000 · begonnen am 10. Apr 2008 · letzter Beitrag vom 11. Apr 2008
Antwort Antwort
Seite 1 von 2  1 2   
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#1

[solved]Thread terminated nicht, obwohl OnTerminate

  Alt 10. Apr 2008, 21:40
Hallo zusammen,

ich habe ein Problem, das sich für mich als ziemlich undurchsichtig erweist:

Ich habe einen Thread erstellt, der ein externes Programm startet und auf dessen Beendigung wartet. Danach soll sich der Thread beenden

Allerdings terminiert der Thread nicht, auch wenn die im OnTerminate zugewiesene "Aktion" abgearbeitet ist.

Delphi-Quellcode:
type TDemuxThread = class(TThread)
  private
    FMPGFileContainer : TMPGFileContainer;
  protected
    procedure Execute; override;
  public
    constructor Create;
    property Terminated;
    property MPGFileContainer: TMPGFileContainer
                               read FMPGFileContainer write FMPGFileContainer;
 end;

...

constructor TDemuxThread.Create;
begin
  inherited Create(true);
  FMPGFileContainer := nil;
end;
[gekürzt]
Delphi-Quellcode:
procedure TDemuxThread.Execute;
begin
  if Assigned(FMPGFileContainer) then
  begin
    FMPGFileContainer.Files.Items[DemuxIndex].Demux;
// MessageDlg('Blubb', mtError, mbYesNo, 0); //-> auskommentiert wegen Antwort 2
  end;
end;
Was im Execute steht, ist völlig unerheblich für mein Problem, ändert nichts daran. Egal ob alles im Execute steht oder gar nichts, das Problem bleibt bestehen (warum auch nicht )

Dieses FMPGFileContainer.Files.Items[DemuxIndex].Demux; öffnet im Grunde per ShellExecAndWait ein externes Programm (DGIndex.exe) und wartet per WaitForSingleObject auf dessen Ende.
Die MessaegBox Blubb poppt ohne Probleme auf

Der Aufruf sieht folgendermaßen aus:
Delphi-Quellcode:
procedure TfMain.btInputDemuxSelClick(Sender: TObject);
begin
  if not Assigned(DemuxThread) then
  begin
    DemuxThread := TDemuxThread.Create;
    DemuxThread.MPGFileContainer := MFC;
    DemuxThread.OnTerminate := DemuxTerminate;
    DemuxThread.Resume;
  end;
end;
und die DemuxTerminate sieht so aus [gekürzt]:
Delphi-Quellcode:
procedure TFMain.DemuxTerminate(Sender:TObject);
begin
 // MessageDlg('wir sind im OnTerminate',mterror,mbyesno,0);//-> auskommentiert wegen Antwort 2
end;
Auch diese MessageBox 'wir sind im onTerminate' poppt auf.

Im CloseQuery schaue ich nach, ob der Thread terminiert ist, denn nur dann darf ich das Programm schließen
Delphi-Quellcode:
procedure TfMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  canclose := true;
  if not DemuxThread.Terminated then
    canclose := false;
end;

Und genau dort hänge ich immer fest. Die Aktion im OnTerminate wurde ausgeführt, alo müsste der Thread doch jetzt terminated sein, oder nicht? Warum also zm Kuckuck kann ich das Programm nicht schließen

gekürzter Quelltext heißt: Es steht noch mehr drin, das habe ich aber alles bei mir schon auskommentiert und hier aus Übersichtlichkeit weggelassen

Nochmal zusammenfassend:
Alles im Thread.Execute wird ohne Probleme ausgeführt.
Aiuch die Anweisungen im Thread.OnTerminate (=DemuxTerminate) werden ausgeführt
Aber mein Thread terminiert danach nicht. Warum?

p.s. ab und zu sieht die 'Blubb' MessageDlg verkrüppelt aus, so wie im Bild, hat das etwas mit dem Problem zu tun?

[edit]
MessageBoxen auskommentiert wegen Antwort 2, jedoch ohne Nutzen
[/edit]
Miniaturansicht angehängter Grafiken
fehler_153.jpg  
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#2

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 21:52
Ähm, mal sone grundsätzliche Frage...du benutzt doch überall Messageboxen. Soweit ich weiß darf in einem Thread doch kein VCL Zeug aufgerufen werden ohne TThread.Synchronize zu verwenden, weil das irgendwie die Threadausführung durcheinander wirft. Versuch doch mal, das programm durchlaufen zu lassen, wenn du alle Messageboxen auskommentiert hast.

Mfg, Alleinherrscher
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#3

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 22:07
Zitat von alleinherrscher:
Ähm, mal sone grundsätzliche Frage...du benutzt doch überall Messageboxen. Soweit ich weiß darf in einem Thread doch kein VCL Zeug aufgerufen werden ohne TThread.Synchronize zu verwenden, weil das irgendwie die Threadausführung durcheinander wirft. Versuch doch mal, das programm durchlaufen zu lassen, wenn du alle Messageboxen auskommentiert hast.
Whoops, ja das hatte ich total vergessen. Danke dafür, das habe ich geändert.

Nützt aber nix, kann das Programm trotzdem nur noch per TaskManager abschiessen.
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#4

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 22:16
Nochwas, was ich nicht ganz verstehe...

Delphi-Quellcode:
type TDemuxThread = class(TThread)
  private
    FMPGFileContainer : TMPGFileContainer;
  protected
    procedure Execute; override;
  public
    constructor Create;
    property Terminated;
    property MPGFileContainer: TMPGFileContainer
                               read FMPGFileContainer write FMPGFileContainer;
end;
Warum schreibst du rein "property Terminated"? Überschreibt das nicht die ursprüngliche Terminated propertry, weshalb sich der Wert nicht mehr ändern, wenn der Thread tatsächlich beendet ist??? Was passiert wenn du die Zeile ebenfalls weglässt?

By the way? Analysis II? Mathe oder Physikstudent?
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
wido

Registriert seit: 2. Jan 2006
122 Beiträge
 
#5

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 22:21
Benutz statt MessageDlg einfach MSDN-Library durchsuchenMessageBox. Im Gegensatz zur VCL ist die Windows API thread safe (bis auf wenige Ausnahmen).

Ansonsten entfern das "property Terminated;". Sollte dann so funktionieren wie Du es Dir vorstellst.
  Mit Zitat antworten Zitat
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#6

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 22:28
Zitat von wido:
Ansonsten entfern das "property Terminated;". Sollte dann so funktionieren wie Du es Dir vorstellst.
Aber wenn ich das entferne, kann ich nicht mehr auf dieses Property zugreifen und der Compiler bringt mir in der CloseQuery den Fehler
[Pascal Error] uMain.pas(197): E2362 Cannot access protected symbol TThread.Terminated

Ich dachte, durch das (erneute) Aufnehmen mache ich die Property public und kann so darauf zugreifen

[OT]
@alleinherrscher:
Beinahe: Ingenieurinformatik.
Hat aber eigentlich absolut nix mit der Datei Analysis II zu tun denn bei diesen Dateien handelt es sich um MPG Dateien (=Aufnahmen auf dem Fernsehen) (hier eben das nostalgische Telekolleg Mathematik)
[/OT]
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#7

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 22:52
Okay, das stimmt natürlich, Terminate ist eine private property... Du könntest im Hauptprogramm "TThread.OnTermiante" verwenden, um eine boolsche variable zu setzten die du in CloseQuery abfragst.

Man kann bestimmt auch dafür sorgen, dass Terminated "public" wird, aber dafür muss man das etwas anders machen... (grade überlegt wie das geht)

Mfg
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
wido

Registriert seit: 2. Jan 2006
122 Beiträge
 
#8

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 10. Apr 2008, 23:17
Hmm, stimmt Terminated ist Private. Naja, prinzipiell könntest Du halt WaitFor nutzen. Also sowas in der Art:

Delphi-Quellcode:
procedure TfMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  // Wenn DemuxThread existiert, warten wir bis der Thread nicht länger ausgeführt wird
  if Assigned(DemuxThread) then DemuxThread.WaitFor;
end;
  Mit Zitat antworten Zitat
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#9

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 11. Apr 2008, 08:10
Zitat von alleinherrscher:
Okay, das stimmt natürlich, Terminate ist eine private property... Du könntest im Hauptprogramm "TThread.OnTermiante" verwenden, um eine boolsche variable zu setzten die du in CloseQuery abfragst.
Danke Dir, das mit der Boolschen Variable hab ich dann auch so gemacht. Ich hatte halt gehofft, eine Variable sparen zu können, wenn ich Thread.Terminated abfrage.

Zitat von alleinherrscher:
Man kann bestimmt auch dafür sorgen, dass Terminated "public" wird, aber dafür muss man das etwas anders machen... (grade überlegt wie das geht)
Irgendwie war ich der Meinung, das würde so funktionieren, peinlich peinlich

Zitat von wido:
Hmm, stimmt Terminated ist Private. Naja, prinzipiell könntest Du halt WaitFor nutzen. Also sowas in der Art:

Delphi-Quellcode:
procedure TfMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  // Wenn DemuxThread existiert, warten wir bis der Thread nicht länger ausgeführt wird
  if Assigned(DemuxThread) then DemuxThread.WaitFor;
end;
WaitFor wartet aber laut OH, bis der Thread beendet wurde, somit würde ich ja die ganze Zeit im CloseQuery festsitzen, bis der Thread irgendwann terminiert

Zusammenfasssend:
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

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

Re: Thread terminated nicht, obwohl OnTerminate aufgerufen

  Alt 11. Apr 2008, 08:26
Also:
1. MyThread.FreeOnTerminate := False;
2. Spendiere dem Thread eine 'Public Property Done : Boolean'
3. Im TMyThread.Create: 'Done := False'
4. Letzte Zeile der 'Execute-Methode' : 'Done := True'
5. Nun kannst Du vom Haupthtread prüfen, ob der Thread fertig ist.
6. Freigeben des Threads nicht vergessen.

P.S.: Die Eigenschaft 'Terminated' dient als Signal von außen. Du musst in der Execute-Methode diese Eigenschaft prüfen, wenn Du den Thread beenden möchtest. Die Eigenschaft wird NICHT gesetzt, wenn der Thread fertig ist.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 13:18 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