![]() |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
IN all cases IdUDPClient is overkill as i explained the from that initial event fired on server side you already have the connection (what called a distinguish identifier for UDP client) along a way to send using SendTo, so introducing IdUDPClient triggering threads that is competing with the server over this connection, is an overhead approach. Now about that last line, your timeout at 250ms monitoring messages is to switch between 1) check if a message is received then what, either timed out at 250ms which contradict the need for real time or 2) try to read from the client ? or send ? Still the whole design is not clear. Just handle the packets in the one recv thread then send from it, even if it is the server triggered event OnRead, because there is something is triggering the main thread to perform some work (a lot of work), and even after all what did you described, this doesn't explain the main thread business. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
IdUDPClient liegt auf einem Datenmodul welches mit
Delphi-Quellcode:
erzeugt wird.
.Create(Nil);
Also nein, es hat keinen Owner. Das Senden mit IdUDPClient sieht so aus:
Delphi-Quellcode:
Eine Prüfung genau an dieser Stelle auf "MainThreadID" und "GetCurrentThreadID" sagt auch, KEIN VCL Kontext.
IdUDPClient.SendBuffer(MyDModul.IdUDPClient.Host,
MyDModul.IdUDPClient.Port, ByteMsg); Das Thema mit den 250ms ist in dem Verarbeitungsthread, hat nichts mit dem Client-Thread zu tun! Das Thema sollten wir nicht weiter betrachten. Richtig, dass Hauptproblem ist nach wie vor die hängende VCL für ~ 7s. Interessant ist, es sind wirklich immer ~ 7s, bei jedem Test. Gibt es eine Möglichkeit, dass ich selber herausbekomme, was der VCL Kontext/Thread gerade gemacht? Ich glaube nämlich nicht, dass das UDP Thema damit eine Rolle spielt. Ich kann es nur dadurch erzeugen, da ich damit so viele Threads gleichzeitig beende. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Weil ich Indy sehe muss ich an TIdAntiFreeze denken.
Bin mir aber nicht sicher ob das an dieser Stelle hilfreich ist. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Aber nur wenn man es im Hauptthread verwendet, was hier ja wohl nicht vorkommt.
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Here a simple test that will create 50000 threads and exits them, no killing just exit gracefully, creating them in fraction of second and exit them in second(s):
Delphi-Quellcode:
Build it for 64bit not 32bit, and don't run it in the debugger as it will kill the IDE, try to increase the created and exited threads to 100k, will there be a big difference.
unit Unit10;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; type TForm10 = class(TForm) Timer1: TTimer; Label1: TLabel; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private procedure CreateOneThread; procedure CreateThreads(Count: Integer); public { Public declarations } end; var Form10: TForm10; implementation {$R *.dfm} var CurrentThreadCount: Integer; const CREATE_MANY_THREADS = 50000; THREADS_STACK_SIZE = 64 * 1024; STACK_SIZE_PARAM_IS_A_RESERVATION = $00010000; function ThreadFunc(Parameter: Pointer): Integer; begin InterlockedIncrement(CurrentThreadCount); Sleep(4000); InterlockedDecrement(CurrentThreadCount); EndThread(0); end; procedure TForm10.FormCreate(Sender: TObject); begin Timer1.Interval := 50; end; procedure TForm10.CreateOneThread; var ThreadId: Cardinal; ThreadHandle: THandle; begin ThreadHandle := BeginThread(nil, THREADS_STACK_SIZE, Addr(ThreadFunc), 0, STACK_SIZE_PARAM_IS_A_RESERVATION, ThreadId); if ThreadHandle <> 0 then CloseHandle(ThreadHandle); end; procedure TForm10.CreateThreads(Count: Integer); begin while Count > 0 do begin CreateOneThread; Dec(Count); end; end; procedure TForm10.Button1Click(Sender: TObject); begin if IsDebuggerPresent then CreateThreads(10) else CreateThreads(CREATE_MANY_THREADS); end; procedure TForm10.Timer1Timer(Sender: TObject); begin Label1.Caption := IntToStr(CurrentThreadCount); end; end. Anyway all Indy components are tied internally to singletons that track their creation and lifetime, using CciticalSection and try to look for singleton that protect from hanging and freezing also for logging...etc.. I am not expert on Indy but you approach even with 35 connection is wrong and cause this. Away from that there is no solution like put this line and it will work fine. ps: when running that test of 50k threads watch the red against the green in Process Explorer. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
The question AJ_Oldendorf did not answer, are there any sort of Synchronize or Thread control functions/method from "TThread." being used ? is there from TThread beyond Create and Execute being used ? like WaitFor ... |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Es geht bei mir um 35 Threads, nicht um 50000. Meine Threads sind Objekte vom Typ TThread und werden mit TThread.Create() erstellt. Warum sind es 35 einzelne Threads mit jeweils einer UDPClient Komponente? Jeder Thread und jeder Teilnehmer, kann zu unterschiedlichen Zeiten unterschiedliche Daten geschickt bekommen. Wird alles in einem Thread abgewickelt wird, müssen sich alle Telegramme durch eine UDPClient-Komponente quälen, so kann jeder Thread an seinen jeweiligen Empfänger (dies ist natürlich auch immer ein anderer, also 35 verschiedene Empfänger) losgelöst arbeiten. Zitat:
Es wird kein Synchronize im Programm verwendet. Es wird kein WaitFor... im Programm verwendet. Class functions/method von "TThread." (wie TThread.Queue) wird nicht verwendet. Ich habe reine Variablen/Objekte vom Typ TThread und die werden mit .Create erstellt und nur über den Variablennamen darauf zugegriffen. Ich möchte nochmal auf das Hauptproblem zurück kommen. VCL Hänger. Wie kann ich in meinem Programm selbstständig feststellen, wer die VCL blockieren könnte bzw was der VCL Thread aktuell macht. Vielleicht wird ja auch aus irgendeinen unbekannten Grund, eine rechenintensive Funktion durch den VCL Thread bearbeitet, was natürlich auch den Hänger erklären würde |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
That example shows how threads are magnificent beasts on Windows, 50k are feather light in creating and exiting, (notice it might be translation problem as i read killing threads), yet it takes only 4 on my 4-core CPU to destroy my whole OS experience, the example is to show you you are after the wrong reason, creating and exiting threads is fast.
Zitat:
See you insist on creating one UDPClient per connection on a server, that is wrong, you said you are not assigning and owner, yet in the same phrase they are on DataModule Zitat:
My final words here is, there is no unknown reason for this, there is broken logic and false assumptions, so no, not Windows faults, not network adapter faults, and not Delphi RTL/VCL fault. Remove the UDPClient creation, make sure you are not creating TDataModule with punch of components on it per client, simplify the logic into one thread per one client doing it all and this freeze will disappear. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
Zitat:
Ich sage auch nicht, dass Beenden von Threads generell lange dauert. Das wäre sicherlich schon jemanden vor mir aufgefallen, wenn es denn so wäre :-D Ich sage nur, wie ich es erzeugen kann, woran es tatsächlich liegt, suche ich ja noch |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Dazu eine Idee? |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Also...
Hier gibt es ja schon viele Fragen und Antworten... Aber. Zitat:
Das ist natürlich der klassische Fehler für die Verwendung eines Threads (Übrings genau das behandle ich in meinem ![]() In einem Thread Queue aufzurufen ist natürlich nicht das Problem, aber nur um "Kleinigkeiten" auf der UI darzustellen. Die eigentliche Verarbeitung muss im Thread passieren. WaitForsingleObject kann man nehmen, aber ich würde ein TEvent verwenden. Da der Server ja immer nur eine Datenpacket nach dem anderen Empfängt würde ich die Aufgabe nicht an N-Thread pro N-Client weiter geben sondern das Datenpacket in eine Threadsichere Quere packen, die von X-Threads abgearbeitet werden. Nur so ein paar gedanken. Mavarik :coder: |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Danke für die Tips.
Das WaitForsingleObject war ja ein Fehler, es wird ja so gemacht:
Delphi-Quellcode:
Das ist aber nur der Thread, der die Daten am Ende verarbeitet. Nicht der UDP Empfang oder Sender Thread...
while not Terminated do
begin Return := MsgWaitForMultipleObjects (Handles, HandleBuffer, False, 251, QS_ALLINPUT); //case Return do //WAIT_OBJECT_0 //WAIT_OBJECT_0+Handles // : begin // while PeekMessage(MessageData, 0, 0, 0, PM_REMOVE) do // begin // Mach irgendwas mit der Nachricht... // end; // end; //WAIT_TIMEOUT //end; //zyklischer Aufruf var sw := TStopwatch.StartNew; var TC : DWORD; var TC2 : DWORD; TC := GetTickCount; //Synchronize(MeineFunktion); //Queue(Nil, MeineFunktion); //ForceQueue(Nil, MeineFunktion); t1 := sw.ElapsedMilliseconds; //Protokollierung von t1 ... TC2 := GetTickCount - TC; //Protokollierung von TC2 ... end ; Hat jemand mal ein Beispiel für Daten, die in eine Threadliste von einem Thread X geschrieben werden und von einem Thread y gelesen werden? Ich möchte aber den Thread y auch per Message oder Event über bestimmte Dinge informieren können von außen. Also ein Beispiel mit threadsichere Queue/Liste UND Event. Dann kann ich das gerne mal versuchen, habe damit noch nichts zu tun gehabt |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Ich kann es aus dem Code zwar nicht direkt ersehen, aber das MsgWaitXXX wartet vermutlich auf den/die Thread(s), die im weiteren Verlauf mit PostThreadMessage beliefert werden sollen. Das wird in der MS-Doku auch genauso beschrieben.
Aber trotz aller oft sicher auch berechtigter Kritik: Das Problem ist offenbar nicht in dem gezeigten Code zu finden. Das Kappen einer größeren Menge von Verbindungen und das daraus folgende Terminieren der Threads ist nicht die Ursache für das Hängen der VCL. Vielmehr löst es diese nur aus. Es geht also darum, die Ursache für den Hänger zu finden. Den Auslöser kennen wir nun ja schon. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Warum sollte ein PostThreadMessage von jemand anderen (von außen) an genau diesen Thread, zu einem warten führen? Das ist mir nicht ganz klar. Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
![]() Zitat:
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
Würde gerne nochmal darauf zurück kommen: Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Hat keinen Effekt auf die VCL. Hätte mich auch gewundert, da alles was mit Logging zu tun hat, an einen zentralen Log-Thread per PostThreadMessage geschickt wird und der liest entsprechend auch seine Queue aus und schreibt dann in die Datei. Muss also noch was anderes sein... |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zeigt doch einfach mal den Quellcode, mit dem die UDPClients gleichzeitig getrennt werden. Hier scheint ja das Problem zu liegen. Eventuell macht der VCL-Thread in der Zeit ja garnichts, sondern wird von Windows erst wieder an die Arbeit gelassen, wenn alle UDPClients beendet sind? Mögliche blockierende Freigabeoperationen(?): Socket-Cleanup bei UDP-Clients erfolgt synchron im Hauptthread? Massenhafte Freigabe (35 Clients) blockiert die Nachrichtenverarbeitung? |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Läuft für jeden UDPClient eine SVCHOST.exe?
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
Delphi-Quellcode:
zugewiesen und die Komponente freigegeben. Das wars.
UDPClient.Active := False
Zitat:
Eine Sache habe ich mittlerweile rausgefunden. Es liegt NICHT an UDP! Ich habe im System noch viel mehr Threads und ich habe mal ein Test gemacht, andere Threads, die völlig andere Aufgaben haben, zu beenden. Hier tritt das gleiche Problem auf. Es ist also ein grundlegendes Problem. Ich werde weiter suchen, woran das liegen könnte. Daher nochmal meine Frage, ihr sprecht von Threadsicheren Listen und keine MessageQueue mit PeekMessage abgrasen und Events triggern. Habt ihr mal ein funktionierendes Beispiel, wie man ein Thread über so eine threadsichere Liste "Nachrichten" zukommen lassen kann und parallel dazu noch mit Events auf bestimmte Dinge triggern kann? Dann würde ich das auch gerne mal umbauen und versuchen |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Ein Profiler wird dir genau zeigen können, was in dem besagten Zeitraum im Code passiert und wo er gerade steht - das kann dir keiner hier sagen, solang es aus verständlichen Gründen nur Codeschnipsel gibt. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Es gibt allerdings lockfreie Queues mit denen das geht! Mann kann die als "Channel" benutzen. Die sind dann zwar Lockfrei jedoch erzeugen die für sich ne menge Aufwand...jedoch diesen aben vollständig ohne die Nebenläufigkeit zu behindern. Die ![]() Falls es die architektonish darum geht einige lang laufende Threads zu haben und diese immer weieder mal mit einer Aufgabe zu versorgen. Dieses problem verspricht die ![]() Ich warte noch auf eine mit "Fearless-Concurency" werbende Multithreading library. Die werde ich dann direkt übernehmen. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Wieder deinstalliert. Eurekalog installiert, im Projekt hinzugefügt, Hang Detection angeklickt und auf 1s gestellt. Anwendung gestartet, Fehlverhalten erzeugt (OnIdle Event wurde auch entsprechend 5s nicht aufgerufen und VCL hängt), Was müsste jetzt passieren? Eurekalog zeigt kein Fenster (hätte ich evtl. erwartet). Ich fahre die Anwendung runter. Auch keine LogDatei mit irgendwelchen Infos zu dem Hänger gefunden. Gibts noch ein Trick? Genau aus dem Grund, wollte ich es selber finden, da auch die Profiler keine Wunderlösung sind und entsprechend konfiguriert oder ähnliches gemacht werden muss. Ich sage nicht, dass die nicht funktionieren. Ich sage nur, es ist kein installieren und Fehler wurde gefunden im Programm. Hier vielleicht jemand ein Tipp dazu? Zitat:
Aber irgendwie scheint es keine Beispiele dazu zu geben, wo man sich das konkret angucken und nutzen könnte. Zum aktuellen Zeitpunkt helfen die Denkanstöße leider nicht wirklich |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Meine letzter Stand ist das wenn man es ganz genau nimmt keine block free Queue existiert.
Queue ist sie nicht wirklich "lock-free", sondern eher ein Thread-sicheres Kommunikationsmittel mit minimaler Sperrung, besonders optimiert für mehr Leser als Schreiber oder umgekehrt. Der Grund ist das immer TMonitor verwendet wird. Und TMonitor arbeitet mit lock. Ausnahme: Lock-Free Ring-Buffer. Habe aber keine Erfahrung damit. Übersicht: Option / Thread-sicher / Echt lock-free / Einfach zu nutzen / Performance TThreadedQueue<T> / ✅ / ❌ / ✅ / Hoch Deltics LockFreeQueue / ✅ / ✅ / ✅ / Sehr hoch Eigene Ring-Buffer / ✅ / ✅ / ❌ (komplex) Extrem hoch Windows SLIST APIs / ✅ / ✅ / ❌ (sehr komplex) Extrem hoch |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Eine Idee wäre: Ein array[0..N] of Queue, bei dem jeder Thread genau eine eigene Queue hat.
Delphi-Quellcode:
Keine Ahnung ob das geht. Aber so würde immer nur ein Thread schreiben und nur der Hauptthread lesen.
ThreadQueues: array[0..MaxThreads - 1] of TThreadedQueue<string>;
constructor TWorkerThread.Create(AQueueIndex: Integer); begin inherited Create(False); FQueueIndex := AQueueIndex; end; procedure TWorkerThread.Execute; var Msg: string; begin while not Terminated do begin Msg := Format('Thread %d arbeitet...', [FQueueIndex]); ThreadQueues[FQueueIndex].Enqueue(Msg); Sleep(Random(100)); end; end; |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Meine Idee dazu wäre ja, für jeden Thread eine eigene Liste anzulegen ähnlich dem Konstrukt was ich mal von Sebastian erhalten habe:
Delphi-Quellcode:
Das müsste soweit mit der Abarbeitung einer Liste mit Nachrichten ja gehen oder habe ich was übersehen?
TDataQueue = class
private FQueue: TQueue<TDataRec>; FLock: TCriticalSection; public constructor Create; destructor Destroy; override; procedure Enqueue(const Data: TDataRec); function Dequeue: TDataRec; end; constructor TDataQueue.Create; begin FQueue := TQueue<TDataRec>.Create; FLock := TCriticalSection.Create; end; destructor TDataQueue.Destroy; begin FQueue.Free; FLock.Free; inherited; end; procedure TDataQueue.Enqueue(const Data: TDataRec); begin FLock.Acquire; try FQueue.Enqueue(Data); finally FLock.Release; end; end; function TDataQueue.Dequeue: TDataRec; begin FLock.Acquire; try if FQueue.Count > 0 then Result := FQueue.Dequeue else begin Result.Clear; end; finally FLock.Release; end; end; TMyThread = class(TThread) private FDataQueue: TDataQueue; protected procedure Execute; override; public constructor Create(ADataQueue: TDataQueue); end; constructor TMyThread.Create(ADataQueue: TDataQueue); begin FDataQueue := ADataQueue; Inherited Create(False); end; procedure TMyThread.Execute; var RecData : TDataRec; begin while not Terminated do begin if Terminated then Exit; if Assigned(FDataQueue) then begin if FDataQueue.Count > 0 then begin RecData := FDataQueue.Dequeue; //Hier etwas mit den Daten/der Nachricht machen end else begin Sleep(1); end; end; end; end; Irgendein anderer Thread trägt dann in die Liste die Daten so ein:
Delphi-Quellcode:
FDataQueue.Enqueue(Daten);
Wie würde man aber das Konstrukt oben noch umbauen, damit es auch mit Events arbeitet. So pollt der Thread ja die ganze Zeit die Liste ab, deswegen auch das Sleep, damit die CPU Auslastung runter geht. Jetzt möchte ich dem Thread aber auch noch bestimmte Events schicken z.B. aus meiner Ursprungsvariante das PostThreadMessage zum terminieren des Threads |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Übrigens nochmal zu meinem Hauptproblem mit dem VCL Hänger.
Ich habe festgestellt, dass der Hänger nur passiert, wenn die Anwendung als 64bit compiliert wurde. Unter 32bit passiert es nicht. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Wenn dir der standard reicht. Alle Objekte von Delphi haben einen monitor. Damit kannst du den zugriff auf dieses Objekt threadsicher machen. Das heist DU blockiert alle zugriffe auf das Objekt bis auf einen und alle threads warten in einer warte schlange und stehen so lange bis sie drann sind. TMonitor leistet das selbe wie TCriticalsection...nur das der Monitor halt schon teil des Objekts ist, während TCriticalsection von dir in alle möglichen kontexte gesetzt werden kann.
Delphi-Quellcode:
Das macht den Zugriff auf MessageQueue wenn konsequent über all so angewendet threadsicher, durch blockieren der nebenläufigkeit im Tmonitor.enter!
TMonitor.enter(MessageQueue);
try MessageQueue.add('einen text'); finally TMonitor.exit(MessageQueue); end; Threads können pausiert und aktiviert werden über TEvent...es ist ein signal
Delphi-Quellcode:
var ZweiThreadsKennenMich := TEvent.create;
ZweiThreadsKennenMich.ResetEvent; //Event Nicht triggered TTask.run( Procedure Begin if ZweiThreadsKennenMich.Waitfor(60000) = wrSignaled then PlaySound else begin //zu lange gewartet ZweiThreadsKennenMich.ResetEvent; end end ); ZweiThreadsKennenMich.SetEvent; // triggered das event und Sound wird abgespielt. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Wie würde dein Beispiel denn aussehen, wenn du es mit 2 verschiedenen Events ausstattest und das in meinen Thread implementierst, der ja bereits die MessageQueue pollt? Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
Zum Profiling: - Anwendung mit mapfiles detailed bauen (am besten auch debug dcus Haken setzen) - ![]()
Delphi-Quellcode:
, was dem Profiler mitteilt, dass es ab hier losgehen soll, danach ggf dasselbe mit OFF. Dann ein Blick ins Ergebnis, was da auftaucht. Gut möglich, dass das nicht zielführend ist. Dann kann man noch mit VTune schießen.
OutputDebugString('SAMPLING ON')
Oder man geht ganz pragmatisch über den Sysinternal Process Explorer her und schaut sich den Callstack zum Zeitpunkt des Freezes an - nicht selten der Fall, dass ich bei sowas direkt ein WaitForSingleObject oder ähnliche Kandidaten finde. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Delphi-Quellcode:
aufrufen, zu dem Zeitpunkt vor dem Hänger und
OutputDebugString('SAMPLING ON')
Delphi-Quellcode:
wenn der Hänger vorbei ist, richtig?
OutputDebugString('SAMPLING OFF')
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
habe mal nachgesehen... tatsächlich sind nur diese LLVM basiert DCCIOSARM DCCIOSARM64 DCCAARM DCCAARM64 DCCLINUX64 DCCOSX64 also ist Windows64 einfach nur ein sau langsamer compiler, ohne guten grund. Das hat mich wohl in die irre geführt. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Liste der Anhänge anzeigen (Anzahl: 2)
@Stevie:
Moin, habe das mal untersucht und nachdem ich auf den Stop Button im Profiler geklickt hatte, kam nach ein paar Sekunden die Anzeige, dass das Programm keine Rückmeldung mehr hat. Im Taskmanager waren 0% CPU Auslastung unf 12MB Speicher belegt. Meine Anwendung lief währenddessen noch weiter. Diese habe ich dann manuell beendet und dann kam der Profiler auch wieder "zurück". 94% Local und Global Ratio mit 4828 Samples ist die win32u.dll mit dem Aufruf NtUserMsgWaitForMultipleObjectsEx. Ich denke mal, dass heißt, dort steht er am längsten drinne oder? Das ist eigentlich auch klar, da dieser Aufruf von meinen Threads überall so gemacht wird (mit der MessageQueue) und dann anschließend mit dem PeekMessage. Im Profiler die ersten Funktionen, die direkt mit meinem Quelltext zu tun haben, sind bei einem Ratio von 0.04% und <4 Samples. So richtig sagt mir das jetzt erstmal noch nichts Edit: Ich habe zu dem Thema Thread, Queue und Events ein separaten Beitrag aufgemacht, da es in diesem Beitrag eigentlich um die Analyse des VCL Hängers gehen soll |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
So, neue Erkenntnisse:
Aufgrund des Profilers von Stevie, bin ich darauf aufmerksam geworden, dass ich den Hänger 2x nicht nachstellen konnte. Warum? Weil die Exe aus dem Profiler gestartet wurde und nicht aus der IDE. Nochmal den Test ohne Profiler gemacht und es ist tatsächlich so. Starte ich die Anwendung aus der Delphi IDE, kann ich den Fehler jedes Mal reproduzieren. Starte ich die Anwendung OHNE die Delphi IDE, ist es nicht mehr reproduzierbar. Mehrmals mit beiden Konstellationen versucht und immer das gleiche Ergebnis. Also hängt sich der Debugger da irgendwo rein und erzeugt den Hänger in irgendeiner Form... Na toll, muss man erstmal drauf kommen |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Hast Du schon mal den Application Verifier probiert?
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Das kann auch umgekehrt auftreten, nämlich, dass es im Debugger nicht passiert. Das heißt allerdings nicht, dass das Debuggen direkt mit dem Fehler zu tun hat. Es bedeutet nur, dass es diesen leichter oder schwerer nachstellbar macht. Ein Punkt, der direkt die Delphi IDE betrifft: Diese setzt mit timeBeginPeriod..timeEndPeriod systemweit die Timer-Auflösung herunter, ich glaube auf 1. Dadurch verhalten sich insbesondere Aufrufe von Sleep anders. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:52 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