![]() |
Thread killen
hi,
bei der Entwicklung meines DFM_Editors musste ich festellen, das die ObjectBinaryToText-Funktion von Delphi 3 bei binären Delphi 7-Formularen (als Resource in exe/dll) manchmal in einer Endlosschleife festhängt: procedure ConvertProperty procedure convertValue while not Reader.EndOfList do begin NewLine; ConvertValue; end; Also hab ich mir gedacht, diesen code in einen Thread auszulagern, um ihn bei bedarf beenden zu können. im TThread.execute mache ich nur das ObjectBinaryToText, und setze ein flag für waitforsingleobject (welche nach dem terminate noch 10 sek wartet bevor der thread hard gekillt wird) der thread wird erzeugt und das terminate-event zu gewiesen:
Delphi-Quellcode:
wenn der thread gekillt wird, bekomme ich eine external Exception (Zugriffsverletzung). ich kann mir nur nicht erklären, woran das liegt.
procedure TForm_ChooseRes.ThreadTerminate(Sender: TObject);
begin //Sender.Free; convThread:=nil; threadDone:=True; Btn_StartThread.Enabled:=true; Btn_StopThread.enabled:=false; end; convThread:=TConvertThread.create; convThread.OnTerminate:=ThreadTerminate; ThreadKilled:=false; der thread wird so gestartet (suspended): convThread.SetStreams(rs,ms); //die zu verarbeitenden Streams übergeben convThread.setMethod(cmBinToTxt); ResetEvent(hEvent);//flag für waitforsingleobject convThread.resume;Thread starten threadDone:=false; while not (threadDone or ThreadKilled) do application.ProcessMessages; //einfrieren der GUI verhindern if not ThreadKilled then begin ms.position:=0; s.LoadFromStream(Ms); end; und so versuche ich ihn zu beenden: if assigned(convThread) then begin id:=convThread.ThreadID; convThread.terminate; res:=waitforsingleObject(hEvent,10000); if res=WAIT_TIMEOUT then begin terminateThread(ID,0); ThreadKilled:=true; end; end; den kompletten source gibts unter: ![]() der thread ist in der thread_convert.pas definiert Hoffe, ihr könnt mir helfen. Gruß Frank [edit=SirThornberry]Delphi-Tags gesetzt Mfg, SirThornberry[/edit] |
Re: Thread killen
Der Thread ist selbst dafür verantwortlich, zu erkennen, dass er beendet wurde.
Also muss innerhalb der Schleifen das Property Terminated abgefragt werden:
Delphi-Quellcode:
Man muss auch nicht in jeder Schleife dieses Property Terminated abfragen.
while (not Reader.EndOfList) and (not Terminated) do
begin // arbeiten end; Es reicht, wenn dies an strategisch günstigen Stellen eingebaut wird. Beispiel: der Thread soll ein Bild mit 1000 * 1000 Pixeln errechnen. Man braucht nun nicht bei jedem Pixel prüfen, ob der Thread terminiert wurde; er reicht aus, dies bei jeder neuen Bildzeile zu tun. |
Re: Thread killen
wenn das ginge würde ich es machen...
leider geht dieses Abfragen des Flags nicht, da ich in dem Thread nur die Delphi-Funktion aufrufe, diese selber hängt. Wäre es nicht ein OS-Projekt könnte ich die Sources verwenden um mir ne eigene Funktion zu basteln um darin das flag zu prüfen, aber das würde sicherlich gegen Copyrights verstoßen Gruß Frank |
Re: Thread killen
Zitat:
Delphi-Quellcode:
// Achtung: TerminateThread möchte das Hanlde nicht die ID des Threads
if not TerminateThread(convThread.Handle, 99) then // bei Fehler eine Exception auslösen // die Message könnte zur Problemlösung beitragen RaiseLastWin32Error; convThread.Free; |
Re: Thread killen
gut, zugriffsverletzung ist jetzt nicht mehr, jedoch hängt jetzt das Programm beim versuch den MemoryStream freizugeben, den ich dem thread zum verarbeiten mitgegeben habe...vermutlich ist der thread noch nicht gekillt. Es wird kein Fehler ausgespuckt (LastWin32Error).
ich benutze deshalb die refernzen auf die streams, weil im Falle des Abschießens ja der Speicher nicht freigegeben wird, den der Thread belegt. Sonst hätte ich im thread eigene Streams verwendet und per assign oder write kopiert. |
Re: Thread killen
Tja, nun kommt der harte Kampf mit dem Debugger (bei Threads besonders schwierig)
Vielleicht hilft dir das etwas weiter: ![]() |
Re: Thread killen
bringt leider auch nix, weder debugview (zeigt nix an) noch assert (Pointer gültig) bringt mich weiter, der thread taucht noch nicht mal im Thread-Fenster der IDE auf
kann es sein, dass der thread die 2 Stream-pointer sperrt, so dass ich die nicht freigeben kann? wie kann man das umgehen? Gruß Frank |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:40 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