Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 05/26/24 in all areas

  1. Anders Melander

    How to debug a Not Responding program element

    You must be thinking of DOS/Windows 3.x. All version of Windows since Windows 95 has supported threading. Your screenshots aren't really showing us the call stack. Make sure that after your pause that you switch to the main thread (open the thread list, double click the topmost thread). I would keep madExcept installed if I were you and occasionally enable its memory overwrite detection for your application. That is how I found and fixed some of the memory overrun bugs in NeoLemmix.
  2. Stefan Glienke

    Delphi on Surface Pro with Qualcomm CPU?

    Given the current issues regarding optimization that all LLVM-based Delphi compilers (that is all but the two Windows ones) have I am tempted to say that an x86 or x64 binary using the emulation layer might be faster than what a compiler that directly targets ARM would produce today. There are multiple reports about this and it boils down to "need to migrate to a newer LLVM version" which we have been told for years now - since recently the C++ Builder side was migrated to a recent LLVM version I hope that now the Delphi side gets addressed. https://quality.embarcadero.com/browse/RSP-9922 https://quality.embarcadero.com/browse/RSP-17724 https://quality.embarcadero.com/browse/RSP-25754 https://quality.embarcadero.com/browse/RSP-28006
  3. @Willicious: have a look at the .patch I attached. That are 2 relatively small changes that improve the situation a lot from what I can see. It caches the group for which the PackTalismanInfo has been generated so it can skip that time-consuming process if the selected group is still the same. And it uses the .OnExpanded handler I mentioned above. SuperLemmixPlayer-18-27-08.patch
  4. @Willicious: I managed to get all relevant code from github and have it compiling and running. How do I reproduce this? The only bit of a hang I've seen is when I click one of the larger level group nodes - then it takes quite a while because of hundreds of buttons and labels being created on the fly. And another thing which makes this worse, there are many updates, i.e. SetInfo calls, even though the selected tree node hasn't even changed - a simple cache of what was previously selected would improve that situation - or at least remove the Click and DblClick handlers which call SetInfo - any click will rebuild the GUI even though the selected node has not changed.
  5. OK, But evidently your application usage of Sleep is showing a problem if understanding its impact, see, Sleep(1) aka sleep for 1 millisecond by default will be 1000/64=15.625 ms, limiting that specific path of code to 64 time per second, this will affect UI greatly, so : 1) Search for every Sleep call in your project from the main thread and remove them, don't use Sleep in main thread not for 1 or even 0 ms, they makes no sense, for background thread it is understandable and useful, but again if the main thread will wait for background thread to finish rendering an animation to paint it then again UI will behave as you described. 2) In my life i may be have used ApplicationIdle few times that can be counted on hand, mostly were to logout or clean up and close stuff or finish opened procedure to not causing blocking something online, but i have removed tens of these handlers from projects that are not mine, due the abuse and misunderstanding of usage, ApplicationIdle is healthy way to see that your UI is responsive the more is called the better, and never use it for something take long time, if needed then start background thread to do it. 3) Your animation most likely is the cause, this is my guess, a thread is doing something while main thread is waiting on it to paint, that is wrong approach, let the thread render (prepare what ever), on other hand use a timer, simple timer with adequate interval to see if that thread or the animation is ready to be painted then draw/paint it, and exit, don't use interval higher than 60 per second, as this is useless and waste of time, on other hand try to centralize all your animations with one timer and one class that do the draw/paint, you don't need every animated button to use 60 message per second, right ? because this will starve UI from handing message and produce the mentioned behavior.
  6. Well ApplicationIdle definitely contributed to your program not handling the window message queue in a timely manner. But for sure it might not be the only one contributing to it. If you keep ApplicationIdle commented out and repeat the steps to get the call stack again, what do you get? Also, is there anything unusual on the form being shown? Does it already take unusually long for the modal form to show up? Coming back to a previous point of mine, which you seemed to have misunderstood: are there any TActionList components in this project? Actions are updated with the same mechanism, i.e. from within TApplication.Idle. If that takes long, the symptoms would be very much the same.
  7. Anders Melander

    How to debug a Not Responding program element

    Okay, so you are doing something in Application.OnIdle. My guess is that you are doing too much (it's taking too long) and thus slowing everything down. Application.OnIdle is called inside the message pump loop when the the message queue is empty. If you do something in OnIdle that take a bit too long the message pump will be slow to react to new messages in the queue. It could also be that you produce a lot of new messages in OnIdle and thus flood the message queue and keep the loop busy all the time. My guess is that OnIdle is used for animation so the messages are probably mostly WM_PAINT and WM_TIMER. Anyway, have a look at what the OnIdle handler is doing. Does the problem go away if you disable that?
  8. Anders Melander

    How to debug a Not Responding program element

    With regard to madExcept; Nothing. You just enable it for your project, check the freeze detection and run the application. If the application isn't pumping the message queue then madExcept will detect that and pop up its usual message box with a stack trace and options to terminate, restart, etc. However, you would only need to do all this if you cannot reproduce the problem in the debugger. If you can reproduce in the debugger you will get the exact same information by just pausing the application and examining the call stack of the main thread in the debugger. No. I believe it was possible to break into the debugger using F12 in Windows XP but I think that option was removed (by Microsoft). I have a registry hack somewhere that enables it again, but I don't have time to find it right now. I think it's related to this: https://learn.microsoft.com/en-us/windows/win32/debug/configuring-automatic-debugging Maybe someone else here knows the answer.
  9. Both the "program not responding" and the delay between clicking a tree node and hitting the breakpoint indicate that your program becomes very slow to process its window message queue. Unfortunately there are many reasons why this is the case. Some ideas that come to my mind are: 1. If you know in advance which node to click to experience the delay, press Pause ASAP after clicking and before hitting the breakpoint (a shortcut won't help, since while you click your program is active and not the IDE). Do this a couple of times to learn where your program typically spends that delay. If you end up in a similar spot in your code more than once, chances are you're looking at the cause (check the call stack!) 2. Do you use threads/tasks in connection with .Synchronize calls? Anything lengthy and blocking in synchronize has the potential to cause such effects. 3. Do you have Action(List) OnUpdate handlers that could take a bit longer? Depending on how complex your GUI is, these handlers might get called a LOT, so they should never do anything costly - if so, consider a caching mechanism. 4. Is this a normal VCL TTreeView? These are known to become quite inefficient with a couple of thousand nodes. Depending on what you do, maybe even with less than that. Of course these are all things to keep in mind even if you go down the OutputDebugString route.
  10. Variable not initialized - I set that one to raise a compile error - because those WILL bite you. Also, you will get that if you init the variable inside a try block, instead of before the block. Hints are often nearly as important as warnings. Value never used can f.x. mean that you are referring to the wrong variable elsewhere you are mistakenly replacing the value elsewhere before the one you initially set could be used or, you didn't need to set that value because it would have been set elsewhere anyways
×