![]() |
AW: Probleme mit Enter/LeaveCriticalSection
Zitat:
TimerOnTimer Aufrufe sind immer im Mainthread |
AW: Probleme mit Enter/LeaveCriticalSection
Zitat:
|
AW: Probleme mit Enter/LeaveCriticalSection
Ein solcher Lock könnte so aussehen:
Delphi-Quellcode:
Der Mainthread macht ungefähr so etwas:
Flag := False;
while (not Flag) do;
Delphi-Quellcode:
ProgrammCodeAusführen reagiert z.B. mal auf das Klicken eines Buttons oder auf das Feuern eines Timers.
repeat
TastaturAbfragen; MausAbfragen; EreignisseAbfragen; ControlsZeichnen; ProgrammCodeAusführen; until WennProgrammGeschlossen Wenn ProgrammCodeAusführen lange dauert, dann kann der Rest erst mal auch nicht mehr erfüllt werden und das Programm "hängt". Wenn Du im Mainthread o.g. Lock verwendest kommt das Programm nie mehr raus, da Flag nie auf True gesetzt werden wird. Ohne nebenläufige Threads, die das Flag wieder umschalten, kann man so etwas also nicht umsetzen. Ich hoffe, dass das nicht ganz falsch ist (wenngleich natürlich stark vereinfacht). Eine Überlegung zum ProcessMessages: Wenn im ProgrammCodeAusführen Application.ProcessMessages aufgerufen wird, werden unbehandelte Messages abgearbeitet. Dazu wird ProgrammCodeAusführen unterbrochen und ggf. rekursiv erneut aufgerufen. Ist das so richtig? Insofern dürften die Timer im Beispiel die Logs nicht mehr durcheinander bringen, wenn man das ProcessMessages weg lässt, da sich die Timerbehandlungen dann immer schön in den Kreislauf des Mainthreads einfügen und kein rekursiver Aufruf erfolgen kann. Richtig? (Ich kann das jetzt nicht testen) |
AW: Probleme mit Enter/LeaveCriticalSection
Zitat:
Beispiel:
Delphi-Quellcode:
Einfach mal Application.Processmessage rein nehmen und "wundern"...
procedure TForm189.Button1Click(Sender: TObject);
begin Timer1.Enabled := true; end; procedure TForm189.FormCreate(Sender: TObject); begin FCount := 0; Timer1.Interval := 25; end; procedure TForm189.Timer1Timer(Sender: TObject); begin Memo1.Lines.Add(FCount.ToString); inc(FCount); Sleep(100); // Application.ProcessMessages; dec(FCount); end; |
AW: Probleme mit Enter/LeaveCriticalSection
Liste der Anhänge anzeigen (Anzahl: 2)
Ich habe das nochmal ein wenig umgebaut.
Hier wird ProcessMessages 20 mal ausgeführt und dann 20 mal nicht mehr. Dann wird der Timer ausgeschaltet und dadurch die ersten 20 Logs "nachgeholt". (Anbei Projekt für XE3 + Exe) EDIT: Noch eine kleine Änderung:
Delphi-Quellcode:
So sieht man, dass der Rest noch abgearbeitet wird, während der Timer schon deaktiviert ist.
procedure TForm1.Timer1Timer(Sender: TObject);
var I: Integer; S: string; begin if (Memo1.Lines.Count > 40) then Timer1.Enabled := False; inc(FCount); Memo1.Lines.Add(IntToStr(FCount) + ' ' + FormatDateTime('zzz', Now) + ': '); for I := 0 to 20 do begin Sleep(100); if Timer1.Enabled then S := '+' else S := '-'; Memo1.Lines[Memo1.Lines.Count - 1] := Memo1.Lines[Memo1.Lines.Count - 1] + ' ' + IntToStr(Memo1.Lines.Count) + S + IntToStr(I); if (Memo1.Lines.Count < 20) then Application.ProcessMessages; end; dec(FCount); end; |
AW: Probleme mit Enter/LeaveCriticalSection
Zitat:
|
AW: Probleme mit Enter/LeaveCriticalSection
In Deinem Test kommt das Programm nie dazu, die zurückgestellten Aufgaben abzuarbeiten. Es hängt sich letztlich auf und lässt sich nicht beenden.
Mein Test zeigt (besser), dass die zurückgestellten Logs später noch abgearbeitet werden (nämlich wenn keine weiteren ProcessMessages mehr dazwischen funken). Ist ja nicht weiter wichtig, aber führt vielleicht schneller zur Erleuchtung bei denjenigen, die sich mal damit auseinander setzen wollen. |
AW: Probleme mit Enter/LeaveCriticalSection
Zitat:
Ich logge per Thread in einen Queue, damit mein Hauptprogramm durch Threading angehalten wird... Aus dieser Queue schreibe ich dann aus einem Thread per Queue nicht syncronize auf die UI. |
AW: Probleme mit Enter/LeaveCriticalSection
Zitat:
Gruß K-H |
AW: Probleme mit Enter/LeaveCriticalSection
Huch!?
Ich habe Dein Beispiel aus #24 nachgebaut und mich anweisungsgemäß gewundert. :mrgreen: Dort hast Du einen Timer benutzt, von Threads ist dort nichts erkennbar. Ich habe die Demo etwas erweitert, damit man noch besser sieht, dass Application.ProcessMessages die Timer-Behandlung unterbricht und rekursiv aufruft. Du hast doch damit angefangen!!! :stupid: (ich habe das nur etwas erweitert) Das Eingangsproblem war doch, dass die erwartete serielle Abarbeitung trotz CS nicht funktionierte. Es ist m.E. ersichtlich geworden, dass dies durch Application.ProcessMessages verursacht ist. EDIT: Man könnte natürlich das Beispiel noch um Threads und eine CriticalSection erweitern um die Ausgangssituation noch genauer nachzubilden, aber ich denke, das ist nicht unbedingt nötig. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:45 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