AW: Ursache für hängende Applikation herausfinden
Hmm, auch wenn ich die Stelle Application.ProcessMessages() im Code mit Sleep(0) oder Windows.Yield() austausche,
bleibt das ganze (wie gewohnt :wink:) hängen... Daran kann es also nicht (nur) liegen... |
AW: Ursache für hängende Applikation herausfinden
Hi,
First and foremost never ever ever ever use Application.ProcessMessages(); in background thread and anywhere in general !, nothing good will come from it, and will add more failure scenarios that no one can imagine or think of. Now to this whole big thread, it is way more complex than it should be. My suggestion for your case (the code above) to drop it all and replace it with something like the a thread that have one event (not two), single one will do the job perfectly, or even remove the event altogether and use simple Sleep or SleepEx with very short sleep time (interval) like 50ms (1/20 of second), check triggering condition and perform one of the following 1) Enabled / Disabled nothing need to be done, loop again. 2) Exit request, then exit. 3) Need to call or notify the main thread then use PostMessage (simple like that) and loop again. 4) You want more control over timing and intervals then use Sleep(1). 5) Access the conditions from the threads itself only using. From the code i deduce you are using this only for Windows then hide this new small thread in small TWinControl (or an invisible form) or what ever you see fit, and implement the a Message handler for that Message coming form PostMessage, and that is it. On side note : PostMessage will of course use a window message, and most importantly if for some reason the message queue is full or blocked (the messages are not being process for other defect or bugs) then Synchronize from a thread will not be helpful too and will only make finding the real bug/flaw harder, Synchronize will only waste your time finding the bug in almost every scenario were things went wrong. Also if PostMessage doesn't work or fail then Synchronize will not help either. |
AW: Ursache für hängende Applikation herausfinden
Zitat:
|
AW: Ursache für hängende Applikation herausfinden
Der Aufruf passierte laut Stacktrace 67 Zeilen weiter unten ab dem begin des Execute gezählt. Da ist im geposteten Quelltext ein end. Da müsstest du noch einmal schauen, was dort vorher stand.
Und wenn nun ohne ProcessMessages die Anwendung hängt... sieht der Bugreport noch genauso aus? Dein Timer nutzt ja nicht immer Synchronize. Kann es vorkommen, dass es ohne aufgrufen wird und dort etwas mit der VCL passiert? Zitat:
Nicht die Statusanzeige oder deren Steuerung gehören in den Thread sondern die lange dauernden Aktionen selbst. Alternativ (aber nicht so schön) könntest du auch ein threadbasiertes Fenster anzeigen. Das kann auch direkt aus dem Thread ohne Synchonisierung verwendet werden. Ich habe dafür mal eine kleine Bibliothek angefangen: https://github.com/jaenicke/MTCL Da es dafür mittlerweile doch Interesse gibt, arbeite ich daran vielleicht doch mal weiter... |
AW: Ursache für hängende Applikation herausfinden
Wenn in Application.ProcessMessages wirklich nur die MessageList direkt verarbeitet würde,
dann wäre es egal, die der Thread vermutlich eh nichts in "seiner" Queue hat (bzw. noch keine Queue erstellt war) Aber dort gibt es eben auch noch anderen Code, welcher auf globale Objekte/Variablen zugreift, welche halt nicht thread-safe sind. |
AW: Ursache für hängende Applikation herausfinden
Zitat:
|
AW: Ursache für hängende Applikation herausfinden
Zitat:
Das wäre dann die Zeile
Delphi-Quellcode:
// Methode direkt aufrufen:
try --> _evTimerFunc( Self ); except Zitat:
Zitat:
Da werden externe Prozesse gestartet, Dateien mehrmals hin und her kopiert und angepasst, Reportdaten aktualisiert, eine Paradox-Tabelle mit Daten befüllt und andere Dinge... ...der Ablauf war ursprünglich nicht so aufwändig - es ist aber mit der Zeit immer mehr geworden und jetzt merkt man eben, dass es eine deutlich Verzögerung im Ablauf gibt. Deswegen der Gedanke mit dem "Bitte warten..."-Dialog, in dem auch die aktuell ausgeführte Aktion textuell angezeigt werden soll. Da in der ursprünglichen Version der angezeigte Text nicht aktualisiert wurde (bzw. die Aktualisierung nicht angezeigt wurde, hatte ich den Gedanken mit dem Thread, der den Text im Dialog animiert und refresht. Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
But I'm not sure if I understand everything you mentioned. Maybe you have some example code for it? :oops: So actually I need a dialog who shows some progress messages - the thread should be able to set the text on that dialog (or the whole dialog is the thread) to show the progress even when the main thread is busy... EDIT: BTW, the dialog itself could also be a generated native windows dialog - it must not be Delphi at all ;-) |
AW: Ursache für hängende Applikation herausfinden
Der ganze Ansatz ist schon komplett für die Füße.
Du musst deine komplexen und langen Operationen in Tasks/Threads packen und die geben zwischendrin oder am Ende Bescheid, was Sachlage ist. |
AW: Ursache für hängende Applikation herausfinden
Zitat:
|
AW: Ursache für hängende Applikation herausfinden
Zitat:
Don't push the info (or data) from background thread to main thread or GUI (VCL), let the VCL/GUI poll the status from the threads, but if it is necessary then notify by (well highly recommended) a message, also make the thread limit its notification to time based condition, like lets say we are moving/copying a folder, if that folder have 10k of small files, it makes no sense to notify or update the UI for each of them, right !?, the copying thread will notify once every 1/10 or 1/20 of second and when finished, and that it is, or will not notify anyone/anything, thread is doing his job and updating single place with data, UI will update with timer, here if the OS itself is way overwhelmed with other application or the CPU is very slow, the application and its UI will not block and will not fail beyond what the OS allow it, but will recover nicely when CPU (hardware in general) is relaxed. A modal form can block the VCL/GUI/UI.. and show "please wait.." or "working...", while have a timer to get the current status/operation form the worker threads, here you don't need to time your background threads or their operation, they just updating a list (may be a list, or properties ... whatever) in thread safe way, while your dialog or modal form will have a timer and update. one problem though if the thread operation might take long time and can't be cut or sliced in shorter job, (as example coping 8GB file on SSD or HDD) then nothing can be sliced and here you need to switch to overlapped file operation, https://learn.microsoft.com/en-us/wi...put-and-output Also look at this nice answers https://stackoverflow.com/questions/...fast-file-copy Notice also these are not utilizing the overlapped IO, yet these operation (reading/writing) can have it and you can have timeout on any of these operation, also as in the second answer 512KB buffer while the first will be very slow with 1KB, i would suggest to try to perform a read with less than 64KB on any modern hardware to not waste time, and 512KB sound good too with modern hardware cache buffers, in all cases if one of these operation will block for long time then you need to switch to overlapped and use them exactly as sockets !, you call the operation with overlapped structure having an event then poll on that event, in such design you can cancel the operation any time. The code above can be adjusted to run in background thread and store the current filename(, size, position...etc) inside the thread itself, while your gui with a timer will update the status. I keep telling that : you should not push form a background thread to main, because i saw this many times, code working perfectly for years, here comes new faster and powerful hardware makes things light speed for UI to keep up, that working code in the past is overwhelming the UI, that happened not because the developer was short sighted, but hardware changed and evolved, few months back i fixed a code (not mine but been asked to modernize it) was working for ages, now it fail with unexpected behavior because the client (owner of that legacy software) started to use hardware with SSD and 2.5Gbs connection, in the past it was on HDD and ADSL. Hope that helps. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:01 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