![]() |
AW: Freigabe Thread
achso, wegen der Freigabe in sich selber... Natürlich. Danke.
Nein, eine Exception kommt nicht. Danke! |
AW: Freigabe Thread
Ich habe davon ehrlich gesagt keine Ahnung. Aber ich schätze, dass das Event im selben Kontext steht wie der Thread ansich. Irgendwie so ...
Einfach den Thread ganz abgekoppelt von außerhalb freigeben. |
AW: Freigabe Thread
Thread-Exceptions ausgeben
Delphi-Quellcode:
oder über das Event
type
TAnalyseThread = class(TThread) protected procedure DoTerminate; override; // oder z.B. als MyOnTerminate über OnTerminate end; procedure TAnalyseThread.DoTerminate; begin if Assigned(FatalException) then begin // FatalException ist ausschließlich im OnTerminate/DoTerminate verfügbar var S := Exception(FatalException).Message; // Exception oder Message kopieren/klonen, denn später im Queue ist sie schon weg. TThread.Queue(nil, procedure begin MessageBox(Application.MainFormHandle, PChar(S), 'Thread-Error', MB_OK or MB_ICONERROR); end); end; inherited; end;
Delphi-Quellcode:
oder
constructor TAnalyseThread.Create(CreateSuspended: Boolean);
begin OnTerminate := MyOnTerminate; inherited; end;
Delphi-Quellcode:
Und es ist absichtlich Queue anstatt Synchronize, damit ein Deadlock beim Freigeben verhindert wird.
procedure TAnalyseThread.Execute;
begin try ... // hier dazwischen alles erstellen/freigeben ... nichts im Create/Destroy except on E: Exception do begin var S := E.Message; // Exception oder Message kopieren/klonen, denn später im Queue ist sie schon weg. Queue(procedure begin MessageBox(Application.MainFormHandle, PChar(S), 'Thread-Error', MB_OK or MB_ICONERROR); end); end; end; end; z.B. Thread wartet auf MainThread, aber MainThread wartet im Thread.Free auf das Thread-Ende. PS:
Delphi-Quellcode:
und dann anstatt
type
TAnalyseThread = class(TThread) public OnReady: TNotifyEvent; constructor Create(OnReady: TNotifyEvent=nil); end; constructor TAnalyseThread.Create(OnReady: TNotifyEvent); begin inherited Create(not Assigned(OnReady)); Self.OnReady := OnReady; FreeOnTerminate := False; end; Zitat:
Delphi-Quellcode:
FreeAndNil(AnalyseThread);
AnalyseThread := TAnalyseThread.Create(OnAnalyseReady); |
AW: Freigabe Thread
So eher nicht:
Code:
Erzeugen im Mainthread und im TAnalyseThread-Kontext freigeben ist halt eher ungünstig!
Unit1.TAnalyseThread.Destroy
System.TObject.Free Unit1.TForm1.OnAnalyseReady($2E7DDC0) Unit1.TAnalyseThread.Execute System.Classes.ThreadProc($2E7DDC0) System.ThreadWrapper($2E4A4A0) :7749fa29 KERNEL32.BaseThreadInitThunk + 0x19 :775e76b4 ntdll.RtlGetAppContainerNamedObjectPath + 0xe4 :775e7684 ntdll.RtlGetAppContainerNamedObjectPath + 0xb4 Biete folgende Lösung an:
Delphi-Quellcode:
unit Unit1;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TAnalyseThread = class(TThread) private protected procedure Execute; override; public constructor Create(CreateSuspended: Boolean); destructor Destroy; override; end; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private AnalyseThread: TAnalyseThread; procedure OnAnalyseReady(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin if Assigned(AnalyseThread) then begin FreeAndNil(AnalyseThread); end; AnalyseThread := TAnalyseThread.Create(True); if Assigned(AnalyseThread) then begin // neu, jetzt noch besser! AnalyseThread.OnTerminate := OnAnalyseReady; AnalyseThread.Start; end; end; procedure TForm1.OnAnalyseReady(Sender: TObject); begin // Auswertung des Daten... if Assigned(AnalyseThread) then begin // Wir sind mit allen durch, aber können hier noch nicht freigeben, weil wir noch zu sehr im Sumpf // des Synchronize drin sind (siehe procedure TThread.DoTerminate;). Darum noch ne Extra-Runde durch // die Windows-Botschaftsbehandlung durch TThread.ForceQueue TThread.ForceQueue(nil, procedure begin FreeAndNil(AnalyseThread); end); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin if Assigned(AnalyseThread) then begin FreeAndNil(AnalyseThread); end; end; { TAnalyseThread } constructor TAnalyseThread.Create(CreateSuspended: Boolean); begin FreeOnTerminate := False; inherited Create(CreateSuspended); TThread.NameThreadForDebugging('TAnalyseThread', Self.ThreadID); end; destructor TAnalyseThread.Destroy; begin inherited Destroy; end; procedure TAnalyseThread.Execute; begin // Tue irgendwas bis fertig... end; end. |
AW: Freigabe Thread
Zitat:
Ich schneide mir ja auch nicht den Ast ab, auf dem ich sitze. Von außen erzeugen und von außen freigeben. |
AW: Freigabe Thread
Ok, habs verstanden. Ich mache es im OnAnalyseReady einfach nicht un gut ist. Danke
|
AW: Freigabe Thread
Zitat:
Wie gesagt, im Programm selber werden unbehandelte Exceptions im Thread von Delphi abgefangen (und dann böswillig nicht ausgegeben). Zitat:
Wann haben die das umgebaut? bin mir fast sicher FatalException wurde früher vor Destroy freigegeben. Somit ist es jetzt aber auch im Destroy noch verfügbar. :firejump: [/EDIT] Denn Exceptions in irgendeinem Thread (auch dem MainThread), welche bis zum System durchrauschen, da beendet dann Windows gleich den kompletten Prozess, drum fängt TThread sowas ab. |
AW: Freigabe Thread
auch im Debugger nicht aber liegt wahrscheinlich daran, dass ich einige Exceptions raus genommen habe (absichtlich) und da ist die bestimmt mit dabei
|
AW: Freigabe Thread
Zitat:
An der Stelle sind wir im MainThread-Kontext und forcieren nochmal das abarbeiten weiterer Messages, indem wir das Freigeben per ForceQueue nochmal auf Reisen schicken. |
AW: Freigabe Thread
Zitat:
Code:
paramdata := TEtwas.Create; // Parameter für den Task. Werden am Ende gelöscht.
TTask.Run( procedure var local : Integer; begin try // To was ... // Uebergib das Ergebnis an das Programm TThread.Synchronize( nil, procedure begin Memo1.Text := 'Bin Fertig'; end ); finally paramdata.Free; end; end ); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:05 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-2025 by Thomas Breitkreuz